1

私の見解では、動的にカスタム TabItems (TextseiteTabItem) を追加しています。プロパティ DataContext を使用して、各 TabItem で動作するモデルを指定しました (値を入力します)。カスタム TabItems に close-command を追加しましたが、機能しません。ビューモデルに閉じるコマンドを送信できません。上記は私の試みです..

私のカスタム TabItem:

<sdk:TabItem x:Class="PortfolioCreator.TextseiteTabItem" 
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
           mc:Ignorable="d"
           xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
           xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">

    <sdk:TabItem.Header>
        <StackPanel Orientation="Horizontal">
            <sdk:Label Content="{Binding Seitennummer, StringFormat='Seite {0}', Mode=TwoWay}"/>
            <Button Content="X"
                    Command="{Binding CloseTabCommand, Mode=TwoWay}"
                    DataContext="{Binding ElementName=TemplateTabControl}"
                    CommandParameter="{Binding SelectedItem, ElementName=TemplateTabControl}" />   
        </StackPanel>
    </sdk:TabItem.Header>

    <sdk:TabItem.Content>
        <Grid x:Name="LayoutRoot">
            ...
        </Grid>
    </sdk:TabItem.Content>
</sdk:TabItem>

私からしてみれば:

...
<sdk:TabControl toolkit:DockPanel.Dock="Bottom" ItemsSource="{Binding Tabs}" x:Name="TemplateTabControl"/>
...

私のViewModelでは:

public class PortfolioViewModel : ViewModelBase
{
    public ObservableCollection<TabItem> Tabs { get; set; }

    public RelayCommand<TabItem> CloseTabCommand
    {
        get;
        private set;
    }

    public PortfolioViewModel()
    {
        CloseTabCommand = new RelayCommand<TabItem>(tab =>
        {
            //never reached
        },
        tab =>
        {
            //never reached
        });

        Tabs = new ObservableCollection<TabItem>();

        AddTextseite();
        AddTextseite();          
    }

    void AddTextseite()
    {
        TabItem item = new TextseiteTabItem();
        item.DataContext = new TextSeiteModel();

        Tabs.Add(item);
    }

}
4

4 に答える 4

1

まず、CloseTabCommand現在のコードスニペットでは何もしません//never reachedtab.Visibility = Visibility.Collapsed実行ハンドラーは、またはのようなものを読み取る必要がありますmyTabControl.Items.Remove(myTabItem)

次に、@ Rafalが指摘したように、ViewModelでUI要素を使用することは、MVVMを実装する正しい方法ではありません。閉じ可能なタブアイテムが必要な場合、正しい方法は、汎用コントロールを派生させるか、ViewModelの対応するインスタンスにバインドできる設定可能なUIレイヤーにをCloseableTabItem書き込むことです。確かに、このアプローチはあなたのプロジェクトには複雑すぎるかもしれません。ClosableTabItemBehaviorICommand CloseCommandICommand

于 2012-07-17T13:44:25.943 に答える
1

MVVM を使用しようとしていますが、奇妙なのは、ビュー モデル内の ui 要素 (タブ) のコレクションです。正しい方法は、タブ項目を記述する ViewModel を作成し、そこにコマンドを移動することです。するとバインドします。タブからタブを削除するには、タブ ビュー モデルでイベントを公開し、PortfolioViewModel からアタッチする必要があります。

もちろん、私の変更により、TextseiteTabItem が TablControl に表示されなくなります。しかし、TabControl.ItemTemplate と TabControl.ContentTemplate で簡単に修正できます。

于 2012-07-17T13:07:47.303 に答える
0

ここでは、wpf のクローズ可能なタブを備えたデモ アプリケーションを見つけます。おそらく、Silverlight バージョンでも機能します。

于 2012-07-17T13:46:47.127 に答える
0

これは、この問題に対する私の回避策です。私はそれが良い解決策ではなく、mvvmパターンを壊していることを認めますが、@herzmeisterが言うように、現在私のプロジェクトには他のアプローチが精巧すぎる. (しかし、それは最終的な解決策にはなりません ;-) )

TabItemViewModel:

public delegate void CloseTabItemHandler();

public class TextseiteTabItemViewModel : ViewModelBase
{
    public event CloseTabItemHandler CloseTabItem;
    public RelayCommand CloseTabCommand {get; set;}

    public TextseiteTabItemViewModel()
    {
        CloseTabCommand = new RelayCommand(() =>
        {
            if (CloseTabItem == null) return;
            CloseTabItem();
        });
    }
}

TabItemView:

<sdk:TabItem x:Class="PortfolioCreator.TextseiteTabItemView" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
        xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
        xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">

    <sdk:TabItem.Header>
        <StackPanel Orientation="Horizontal">
            <Button Content="X" Command="{Binding CloseTabCommand, Mode=TwoWay}" />  
        </StackPanel>
    </sdk:TabItem.Header>

    <sdk:TabItem.Content>
        <Grid x:Name="LayoutRoot">
            ...
        </Grid>
    </sdk:TabItem.Content>
</sdk:TabItem>

親ビューモデル:

public class PortfolioViewModel : ViewModelBase
{
    public ObservableCollection<TabItem> Tabs { get; set; }

    public PortfolioViewModel()
    {
        Tabs = new ObservableCollection<TabItem>();

        AddTextseite();
        AddTextseite();
    }

    void AddTextseite()
    {
        var viewmodel = new TextseiteTabItemViewModel();

        TabItem item = new TextseiteTabItemView();
        item.DataContext = viewmodel;

        viewmodel.CloseTabItem += new CloseTabItemHandler(() => 
        { 
            Tabs.Remove(item);
        });

        Tabs.Add(item);
    }
}
于 2012-07-17T16:33:51.103 に答える