TabControlを含むUsercontrol(TabUserControl)があります。そのUserControlのViewmodelは、TabItemのObservableコレクションをロードします。 1つのodこれらのアイテムは別のユーザーコントロールです。タブコントロールにテキストをロードするだけでは問題はありませんが、他のユーザーコントロールをTabUserControlのタブアイテムにロードするにはどうすればよいですか。私はMVVMを使用します。
これが私のコードです:
public class TabItem
{
public string Header { get; set; }
public object Content { get; set; } // object to allow all sort of items??
}
TabUserControlのビューモデル
public class TabViewModel
{
public ObservableCollection<TabItem> Tabs {get;set;}
public TabViewModel()
{
Tabs = new ObservableCollection<TabItem>();
//Tabs.Add(new TabItem { Header = "Overview", Content = new OverviewViewModel() }); How to load a usercontrol here if it's in the ItemCollection?
Tabs.Add(new TabItem { Header = "Overview", Content = "Bla bla bla" });
Tabs.Add(new TabItem { Header = "Two", Content = "Two's content" });
}
}
そして、TabControl XAML:
<TabControl x:Name="_tabControl"
ItemsSource="{Binding Tabs}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header"
Value="{Binding Header}" />
<Setter Property="Content"
Value="{Binding Content}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
TabItemsコレクションにユーザーコントロールのビューモデルをロードしない限り、機能します。 UserTabControlをTabItemにロードするにはどうすればよいですか?すべてのタブアイテムにユーザーコントロールが含まれるようにすることを目的としています。次に、各ユーザーコントロールは独自のことを行います。
私はWPFの初心者なので、誰かが私を助けてくれることを願っています。どうも!
理想的には、TabControl.ItemsSource
はViewModels
のコレクションに設定する必要があり、DataTemplates
は、特定のViewModel
で各UserControl
を描画するようにWPFに指示するために使用する必要があります。
これにより、ビジネスロジック(ViewModels
)とUI(Views
)が完全に分離されます。
例えば、
<TabControl x:Name="MyTabControl"
ItemsSource="{Binding TabViewModels}"
SelectedItem="{Binding SelectedTabViewModel}">
<TabControl.Resources>
<DataTemplate DataType="{x:Type my:ViewModelA}">
<my:ViewAUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type my:ViewModelB}">
<my:ViewBUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type my:ViewModelC}">
<my:ViewCUserControl />
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Header}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
TabControlのDataContextを含むViewModel:
TabViewModels = new ObservableCollection<ITabViewModel>();
TabViewModels.Add(new ViewModelA { Header = "Tab A" });
TabViewModels.Add(new ViewModelB { Header = "Tab B" });
TabViewModels.Add(new ViewModelC { Header = "Tab C" });
SelectedTabViewModel = TabViewModels[0];
レイチェルに答えてくれてありがとう。ただし、コンパイル時自体にDataContextの宣言を強制します。あなたがしたように、各ビューをTabControlのDataTemplate内のそれぞれのViewModelに関連付けます。これをViewModelに移動すると、動的なView-ViewModelリンクを実現できます。方法は次のとおりです。
XAML:
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="Content" Value="{Binding Content}" />
</Style>
<TabControl.ItemContainerStyle>
VM:
public ObservableCollection<TabItem> TabItems { get; set; }
public MainWindowViewModel()
{
TabItems = new ObservableCollection<TabItem>
{
new TabItem{Content = new TabAView() {DataContext = new TabAViewModel()}, Header = "Tab A"},
new TabItem{Content = new TabBView(), Header = "Tab B"}
};
}
アクションデリゲートを使用して、TabSelectionChangedEventでのみTabItemの初期化を遅延および呼び出すこともできます。これにより、UserControlビューに多くのUI要素がある場合、多くのメモリを節約できます。