[英]WPF: TabControl with multiple DataTemplates
I have a TabControl
with multiple DataTemplate
. 我有一个带有多个
DataTemplate
的TabControl
。 the first DataTemplate
will be used for search reasons and the second will be for displaying items obtained from that search. 第一个
DataTemplate
将用于搜索原因,第二个将用于显示从该搜索中获得的项目。 My XAML
code will be as follows: 我的
XAML
代码如下:
<UserControl.Resources>
<!--First template-->
<DataTemplate>
<!-- I will have a DataGrid here-->
</DataTemplate>
<!--Second template-->
<DataTemplate >
<!-- I will have details of one item of the DataGrid-->
</DataTemplate>
</UserControl.Resources>
<TabControl ItemsSource="{Binding }"/>
What I want to accomplish is that in the TabControl
the first tab will contain the first DataTemplate
(the search template) and when I double click on one row of my DataGrid
, a tab will be added with the details of that row (in other words a tab with the second template). 我要完成的工作是,在
TabControl
,第一个选项卡将包含第一个DataTemplate
(搜索模板),当我双击DataGrid
一行时,将添加一个带有该行详细信息的选项卡(换句话说,一个带有第二个模板的标签)。
Since I am using MVVM
, I thought of creating two UserControl
s, one for each template and then catch the double click event, but after this I don't know how to add a tab since now my search template is a UserControl
seperated from the one that contains the TabControl
. 由于我使用的
MVVM
,我想创建两个UserControl
S,为每个模板,然后捕捉双击事件,但在此之后,我不知道如何,因为现在我的搜索模板是添加标签UserControl
从分隔一个包含TabControl
。
So how do I do this? 那么我该怎么做呢?
UPDATE: 更新:
As I read the answers I think I wasn't very clear in stating the problem. 当我阅读答案时,我认为我在陈述问题时并不太清楚。 My problem is how to add tabs with the second template, by catching double click events from the first template.
我的问题是如何通过捕获第一个模板的双击事件来添加带有第二个模板的标签。 I don't have any problem in adding the two templates independently.
我独立添加两个模板没有任何问题。
Rather can creating two UserControl
s, you can create and use a DataTemplateSelector
in order to switch different DataTemplate
s in. 可以创建两个
UserControl
,而可以创建和使用DataTemplateSelector
来切换不同的DataTemplate
。
Basically, create a new class that inhereits from DataTemplateSelector
and override the SelecteTemplate
method. 基本上,从
DataTemplateSelector
创建一个新类,并重写SelecteTemplate
方法。 Then declare an instance of it in the XAML (much like a value converter), and then apply it to ContentTemplateSelector
property of the TabControl
. 然后在XAML中声明它的一个实例(非常类似于值转换器),然后将其应用于
TabControl
ContentTemplateSelector
属性。
If you're going to do this with MVVM, your tab control should be bound to some ObservableCollection
in your VM, and you just add and remove VM's to the collection as needed. 如果要使用MVVM进行此操作,则应将选项卡控件绑定到VM中的某些
ObservableCollection
,然后根据需要将VM添加和删除到集合中。
The VMs can be any type you like and your DataTemplates will show the correct view in the tab just like any other view, so yes, create two UserControls for the two views. VM可以是您喜欢的任何类型,并且DataTemplates会像其他任何视图一样在选项卡中显示正确的视图,因此可以,为这两个视图创建两个UserControl。
public class MainVM
{
public ObservableCollection<object> Views { get; private set; }
public MainVM()
{
this.Views = new ObservableCollection<object>();
this.Views.Add(new SearchVM(GotResults));
}
private void GotResults(Results results)
{
this.Views.Add(new ResultVM(results));
}
}
There are two options: Use datatemplate selector, or use implicit datatemplates and different types for each tabitem. 有两个选项:使用datatemplate选择器,或对每个tabitem使用隐式datatemplates和不同的类型。
1. DataTemplateSelector: 1. DataTemplateSelector:
public ObservableCollection<TabItemVM> Tabs { get; private set; }
public MainVM()
{
Tabs = ObservableCollection<TabItemVM>
{
new TabItemVM { Name="Tab 1" },
};
}
void AddTab(){
var newTab = new TabItemVM { Name="Tab 2" };
Tabs.Add(newTab);
//SelectedTab = newTab; //you may bind TabControl.SelectedItemProperty to viewmodel in order to be able to activate the tab from viewmodel
}
public class TabItemTemplateSelector : DataTemplateSelector
{
public DataTemplate Tab1Template { get; set; }
public DataTemplate Tab2Template { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var tabItem = item as TabItemVM;
if (tabItem.Name == "Tab 1") return Tab1Template;
if (tabItem.Name == "Tab 2") return Tab2Template;
return base.SelectTemplate(item, container);
}
}
<local:TabItemTemplateSelector
x:Key="TabItemTemplateSelector"
Tab1Template="{StaticResource Tab1Template}"
Tab2Template="{StaticResource Tab2Template}" />
2. Implicit Data Templates: 2.隐式数据模板:
public class MainVM : ViewModelBase
{
public ObservableCollection<TabItemVM> Tabs { get; private set; }
public MainVM()
{
Tabs = new ObservableCollection<TabItemVM>
{
new Tab1VM(),
};
}
void AddTab()
{
var newTab = new Tab2VM()
Tabs.Add(newTab);
//SelectedTab = newTab;
}
}
public class TabItemBase
{
public string Name { get; protected set; }
}
public class Tab1VM : TabItemBase
{
public Tab1VM()
{
Name = "Tab 1";
}
}
public class Tab2VM : TabItemBase
{
public Tab2VM()
{
Name = "Tab 2";
}
}
<UserControl.Resources>
<!--First template-->
<DataTemplate DataType="local:Tab1VM">
<!-- I will have a DataGrid here-->
</DataTemplate>
<!--Second template-->
<DataTemplate DataType="local:Tab2VM">
<!-- I will have details of one item of the DataGrid-->
</DataTemplate>
</UserControl.Resources>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.