为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
守候你守候我 2022-01-15 17:21:57
我是 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>
查看完整描述

1 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

您不需要 DataTemplateSelector。只需确保可以自动选择详细的 DataTemplates,而不是为其分配密钥。


您的对象似乎也不需要两个集合。您不妨从一个公共基类派生 Unit 和 Component,并拥有一个基类引用集合。


最后应该有一个视图模型,除了对象集合之外,它还具有当前选定对象的属性。


以这个简化的示例视图模型为例:


public class Base

{

    public int Id { get; set; }

}


public class Unit : Base

{

    public string UnitData { get; set; }

}


public class Component : Base

{

    public string ComponentData { get; set; }

}


public class ViewModel : INotifyPropertyChanged

{

    public event PropertyChangedEventHandler PropertyChanged;


    public ObservableCollection<Base> Objects { get; }

        = new ObservableCollection<Base>();


    private Base selectedObject;


    public Base SelectedObject

    {

        get { return selectedObject; }

        set

        {

            selectedObject = value;

            PropertyChanged?.Invoke(this,

               new PropertyChangedEventArgs(nameof(SelectedObject)));

        }

    }

}

它的一个实例应该分配给窗口的 DataContext:


public MainWindow()

{

    InitializeComponent();


    var vm = new ViewModel();

    vm.Objects.Add(new Unit { Id = 1, UnitData = "Unit Data" });

    vm.Objects.Add(new Component { Id = 2, ComponentData = "Component Data" });


    DataContext = vm;

}

最后,XAML 将是这样的:


<ListBox ItemsSource="{Binding Objects}"

            SelectedItem="{Binding SelectedObject}">

    <ListBox.Resources>

        <DataTemplate DataType="{x:Type local:Unit}">

            <TextBlock>

                <Run Text="Unit, Id:"/>

                <Run  Text="{Binding Id}"/>

            </TextBlock>

        </DataTemplate>

        <DataTemplate DataType="{x:Type local:Component}">

            <TextBlock>

                <Run Text="Component, Id:"/>

                <Run  Text="{Binding Id}"/>

            </TextBlock>

        </DataTemplate>

    </ListBox.Resources>

</ListBox>

<ContentControl Grid.Column="1" Content="{Binding SelectedObject}">

    <ContentControl.Resources>

        <DataTemplate DataType="{x:Type local:Unit}">

            <StackPanel>

                <TextBlock Text="{Binding Id}"/>

                <TextBlock Text="{Binding UnitData}"/>

            </StackPanel>

        </DataTemplate>

        <DataTemplate DataType="{x:Type local:Component}">

            <StackPanel>

                <TextBlock Text="{Binding Id}"/>

                <TextBlock Text="{Binding ComponentData}"/>

            </StackPanel>

        </DataTemplate>

    </ContentControl.Resources>

</ContentControl>


查看完整回答
反对 回复 2022-01-15
  • 1 回答
  • 0 关注
  • 284 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号