Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF:TabControl具有多个数据模板_C#_Wpf_Mvvm_Datatemplate_Tabcontrol - Fatal编程技术网

C# WPF:TabControl具有多个数据模板

C# WPF:TabControl具有多个数据模板,c#,wpf,mvvm,datatemplate,tabcontrol,C#,Wpf,Mvvm,Datatemplate,Tabcontrol,我有一个带有多个数据模板的选项卡控件。第一个DataTemplate将用于搜索原因,第二个将用于显示从该搜索中获得的项目。我的XAML代码如下: <UserControl.Resources> <!--First template--> <DataTemplate> <!-- I will have a DataGrid here--> </DataTemplate> <!--S

我有一个带有多个数据模板的
选项卡控件
。第一个
DataTemplate
将用于搜索原因,第二个将用于显示从该搜索中获得的项目。我的
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 }"/>

我想完成的是,在
选项卡控件中,第一个选项卡将包含第一个
数据模板(搜索模板),当我双击我的
数据网格的一行时,将添加一个包含该行详细信息的选项卡(换言之,是包含第二个模板的选项卡)

由于我使用的是
MVVM
,我想创建两个
UserControl
s,每个模板一个,然后捕获双击事件,但在此之后我不知道如何添加选项卡,因为现在我的搜索模板是一个
UserControl
,与包含
TabControl
的模板分开

那我该怎么做呢

更新:

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);
    }
}
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
s,您可以创建并使用
DataTemplateSelector
在中切换不同的
DataTemplate
s

基本上,创建一个从
DataTemplateSelector
继承的新类,并重写
SelecteTemplate
方法。然后在XAML中声明它的一个实例(很像值转换器),然后将其应用于
TabControl
ContentTemplateSelector
属性


基本上,创建一个从
DataTemplateSelector
继承的新类,并重写
SelecteTemplate
方法。然后在XAML中声明它的一个实例(很像值转换器),然后将其应用于
TabControl
ContentTemplateSelector
属性


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));
    }
}
公共类MainVM
{
公共可观测集合视图{get;private set;}
公共MainVM()
{
this.Views=新的ObservableCollection();
this.Views.Add(newsearchvm(gotrests));
}
私有结果(结果)
{
this.Views.Add(newresultvm(results));
}
}

如果要使用MVVM执行此操作,则选项卡控件应绑定到VM中的某个
可观察集合
,您只需根据需要向集合中添加和删除VM即可

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));
    }
}
公共类MainVM
{
公共可观测集合视图{get;private set;}
公共MainVM()
{
this.Views=新的ObservableCollection();
this.Views.Add(newsearchvm(gotrests));
}
私有结果(结果)
{
this.Views.Add(newresultvm(results));
}
}

有两个选项:使用datatemplate选择器,或为每个选项卡项使用隐式datatemplates和不同类型

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);
    }
}
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";
    }
}
publicobservableCollection选项卡{get;private set;}
公共MainVM()
{
Tabs=可观察到的集合
{
新的TabItemVM{Name=“Tab 1”},
};
}
void AddTab(){
var newTab=new tabitemv{Name=“Tab 2”};
Tabs.Add(newTab);
//SelectedTab=newTab;//您可以将TabControl.SelectedItemProperty绑定到viewmodel,以便能够从viewmodel激活选项卡
}
公共类选项卡ItemTemplateSelector:DataTemplateSelector
{
公共数据模板选项卡1模板{get;set;}
公共数据模板Tab2Template{get;set;}
公共覆盖数据模板SelectTemplate(对象项,DependencyObject容器)
{
var tabItem=作为tabitemv的项目;
如果(tabItem.Name==“Tab 1”)返回Tab1Template;
if(tabItem.Name==“Tab 2”)返回Tab2Template;
返回基地。选择模板(项目、容器);
}
}

2。隐式数据模板:

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);
    }
}
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";
    }
}
public类MainVM:ViewModelBase
{
公共ObservableCollection选项卡{get;private set;}
公共MainVM()
{
Tabs=新的ObservableCollection
{
新选项卡1vm(),
};
}
void AddTab()
{
var newTab=new Tab2VM()
Tabs.Add(newTab);
//SelectedTab=newTab;
}
}
公共类TabItemBase
{
公共字符串名称{get;protected set;}
}
公共类Tab1VM:TabItemBase
{
公共选项卡1vm()
{
Name=“表1”;
}
}
公共类Tab2VM:TabItemBase
{
公共Tab2VM()
{
Name=“表2”;
}
}

有两个选项:使用datatemplate选择器,或为每个选项卡项使用隐式datatemplates和不同类型

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);
    }
}
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";
    }
}
publicobservableCollection选项卡{get;private set;}
公共MainVM()
{
Tabs=可观察到的集合
{
新的TabItemVM{Name=“Tab 1”},
};
}
void AddTab(){
var newTab=new tabitemv{Name=“Tab 2”};
Tabs.Add(newTab);
//SelectedTab=newTa