wpf将不同的数据模板绑定到contentcontrol中不同类型的对象

我是 WPF 和 MVVM 的新手。我要做的是将两个不同的 DataTemplates 绑定到一个 ContentControl 中的两种不同类型的对象。每种对象对应一个DataTemplate。


这两种对象分别称为单元和组件。它们包含不同的属性。例如,一个 Unit 有 3 个属性:Id、Name和Manufacture。一个组件有 3 个属性Id、Type和Materials。示例代码如下:


public class Unit : INotifyPropertyChanged

{

    private int _id;

    private string _name;

    private string _manufacture;


    public int Id

    {

        get {return this._id}

        set

        {

            this._id = value;

            OnPropertyChanged("Id")

        }

    {

    public string Name

    {

        get {return this._name}

        set

        {

            this._id = value;

            OnPropertyChanged("Name")

        }

    {

    public string Manufacture

    {

        get {return this._manufacture}

        set

        {

            this._id = value;

            OnPropertyChanged("Manufacture")

        }

    {

    public event PropertyChangedEventHandler PropertyChanged;

    ...

}

Component 类具有类似的结构。


在 MainWindow 中,左侧有一个 ListBox 列出对象的名称(我以后会将其更改为 TreeView),右侧有一个 ContentControl。我希望当我选择一个对象的名称时,该对象的详细信息将显示在右侧。MainWindow的代码如下:


<Windows.Resources>

    <CollectionViewSource

        Source="{Binding Source={x:Static Application.Current}, Path=UnitItems}"

        x:Key="UnitDataView">

    </CollectionViewSource>


    <CollectionViewSource

        Source="{Binding Source={x:Static Application.Current}, Path=ComponentItems}"

        x:Key="ComponentDataView">

    </CollectionViewSource>


    <CompositeCollection x:Key="AllDataView

        <CollectionContainer Collection="{Binding Source={StaticResource UnitDataView}}" />

        <CollectionContainer Collection="{Binding Source={StaticResource ComponentDataView}}" />

    </CompositeCollection>


<local: PartDataTemplateSelector x:Key="MyDataTemplateSelector"

                                 UnitTemplate="{StaticResource unitTemplate}"

                                 ComponentTemplate="{StaticResource componentTemplate}" />

</Windows.Resources>



守候你守候我
浏览 285回答 1
1回答

慕尼黑的夜晚无繁华

您不需要 DataTemplateSelector。只需确保可以自动选择详细的 DataTemplates,而不是为其分配密钥。您的对象似乎也不需要两个集合。您不妨从一个公共基类派生 Unit 和 Component,并拥有一个基类引用集合。最后应该有一个视图模型,除了对象集合之外,它还具有当前选定对象的属性。以这个简化的示例视图模型为例:public class Base{&nbsp; &nbsp; public int Id { get; set; }}public class Unit : Base{&nbsp; &nbsp; public string UnitData { get; set; }}public class Component : Base{&nbsp; &nbsp; public string ComponentData { get; set; }}public class ViewModel : INotifyPropertyChanged{&nbsp; &nbsp; public event PropertyChangedEventHandler PropertyChanged;&nbsp; &nbsp; public ObservableCollection<Base> Objects { get; }&nbsp; &nbsp; &nbsp; &nbsp; = new ObservableCollection<Base>();&nbsp; &nbsp; private Base selectedObject;&nbsp; &nbsp; public Base SelectedObject&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get { return selectedObject; }&nbsp; &nbsp; &nbsp; &nbsp; set&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; selectedObject = value;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PropertyChanged?.Invoke(this,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new PropertyChangedEventArgs(nameof(SelectedObject)));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}它的一个实例应该分配给窗口的 DataContext:public MainWindow(){&nbsp; &nbsp; InitializeComponent();&nbsp; &nbsp; var vm = new ViewModel();&nbsp; &nbsp; vm.Objects.Add(new Unit { Id = 1, UnitData = "Unit Data" });&nbsp; &nbsp; vm.Objects.Add(new Component { Id = 2, ComponentData = "Component Data" });&nbsp; &nbsp; DataContext = vm;}最后,XAML 将是这样的:<ListBox ItemsSource="{Binding Objects}"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SelectedItem="{Binding SelectedObject}">&nbsp; &nbsp; <ListBox.Resources>&nbsp; &nbsp; &nbsp; &nbsp; <DataTemplate DataType="{x:Type local:Unit}">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <TextBlock>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Run Text="Unit, Id:"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Run&nbsp; Text="{Binding Id}"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </TextBlock>&nbsp; &nbsp; &nbsp; &nbsp; </DataTemplate>&nbsp; &nbsp; &nbsp; &nbsp; <DataTemplate DataType="{x:Type local:Component}">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <TextBlock>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Run Text="Component, Id:"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Run&nbsp; Text="{Binding Id}"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </TextBlock>&nbsp; &nbsp; &nbsp; &nbsp; </DataTemplate>&nbsp; &nbsp; </ListBox.Resources></ListBox><ContentControl Grid.Column="1" Content="{Binding SelectedObject}">&nbsp; &nbsp; <ContentControl.Resources>&nbsp; &nbsp; &nbsp; &nbsp; <DataTemplate DataType="{x:Type local:Unit}">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <StackPanel>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <TextBlock Text="{Binding Id}"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <TextBlock Text="{Binding UnitData}"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </StackPanel>&nbsp; &nbsp; &nbsp; &nbsp; </DataTemplate>&nbsp; &nbsp; &nbsp; &nbsp; <DataTemplate DataType="{x:Type local:Component}">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <StackPanel>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <TextBlock Text="{Binding Id}"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <TextBlock Text="{Binding ComponentData}"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </StackPanel>&nbsp; &nbsp; &nbsp; &nbsp; </DataTemplate>&nbsp; &nbsp; </ContentControl.Resources></ContentControl>
打开App,查看更多内容
随时随地看视频慕课网APP