WPF 和 ObservableCollection<T>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15696467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:22:29  来源:igfitidea点击:

WPF and ObservableCollection<T>

c#.netwpfobservablecollection

提问by KingTravisG

I have an ObservableCollection<IRuleCondition>that I want to display - the IRuleConditioninterface is used by 2 different classes I want to display, a RuleConditionthat simply displays one rule condition (info such as priority, property to check and so on), and a RuleConditionGroup, that can contain 2 or more RuleConditions, grouped in such a way that any of the conditions could match, or all etc.

我有一个ObservableCollection<IRuleCondition>我想显示的 - 该IRuleCondition界面被我想显示的 2 个不同的类使用,一个RuleCondition只显示一个规则条件(信息,例如优先级、要检查的属性等),一个RuleConditionGroup, 可以包含 2或更多RuleConditions,以任何条件都可以匹配的方式分组,或全部等。

In the XAML I was wondering is there a way to display a different ListView.ItemTemplatedepending on what the type is that it encounters in the ObservableCollection<IRuleCondition>? Or would I need to implement two different ObservableCollections?

在 XAML 中,我想知道有没有一种方法可以ListView.ItemTemplate根据它在ObservableCollection<IRuleCondition>. 或者我需要实现两个不同的ObservableCollections 吗?

回答by parapura rajkumar

Here is a simple example of how this works

这是一个简单的例子,说明它是如何工作的

This is how the objects are defined

这就是对象的定义方式

public interface Person
{
    string Name { get; set; }
}

public class Manager : Person
{
    public string Name { get; set; }
}

public class Employee : Person
{
    public string Name { get; set; }
    public string ManagerName { get;set;}
}

This is the MainWindow code behind

这是背后的 MainWindow 代码

public partial class MainWindow : Window
    {
        ObservableCollection<Person> mPeople = new ObservableCollection<Person>();

        public ObservableCollection<Person> People
        {
            get
            {
                return mPeople;
            }
        }

        public MainWindow()
        {
            DataContext = this;
            mPeople.Add( new Employee{ Name = "x" , ManagerName = "foo"});
            mPeople.Add( new Manager { Name = "y"});

            InitializeComponent();
        }
    }

This is the MainWindow XAML

这是主窗口 XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WpfApplication1"
        Title="MainWindow"
        Height="350"
        Width="525">
    <Window.Resources>
        <DataTemplate  DataType="{x:Type my:Employee}">
            <StackPanel Background="Green" Width="300">
                <TextBlock Text="{Binding Name}" />
                <TextBlock Text="{Binding ManagerName}" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate  DataType="{x:Type my:Manager}">
            <StackPanel Background="Red"
                        Width="300">
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>

    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding People}"></ListBox>
    </Grid>
</Window>

As you can see there are two datatemplates one for Manager and one for Employee

如您所见,有两个数据模板,一个用于 Manager,另一个用于 Employee

enter image description here

在此处输入图片说明

And this is how the crappy output looks like. Notice the green and red background and extra field displayed for the Employee compared to the manager

这就是糟糕的输出的样子。请注意与经理相比,为员工显示的绿色和红色背景和额外字段

回答by Kai Wang

Just define two different DataTemplates in the Resources section, one for each RuleCondition type.

只需在资源部分定义两个不同的 DataTemplate,每个 RuleCondition 类型一个。

回答by Greg D

1) Create your two different data templates, just as you say you've already done. 2) Create a custom DataTemplateSelectorto choose the appropriate template.

1) 创建两个不同的数据模板,就像你说的那样。2) 创建一个自定义的DataTemplateSelector来选择合适的模板。

One of your comments states that you're getting an error from your DataTemplateSelector. Verify that you're implementing the class correctly, perhaps paste your implementation. It should be fairly small and straightforward.

您的评论之一指出您的 DataTemplateSelector 出现错误。验证您是否正确实现了类,也许粘贴您的实现。它应该相当小和简单。