C# DataBind到ObservableCollection,仅显示某个派生类的元素

C# DataBind到ObservableCollection,仅显示某个派生类的元素,c#,wpf,xaml,mvvm,observablecollection,C#,Wpf,Xaml,Mvvm,Observablecollection,我正在使用MVVM模式在WPF中开发一个应用程序,遇到了一些可能有点独特的东西 我有一个抽象类MapEntity,它表示可以在应用程序的绘图表面上显示的实体。其他类,如LineEntity、TextEntity等,都是从MapEntity继承的 为了显示这些,我为每种类型创建了一个ObservableCollection,并将其绑定到我的XAML,该XAML获取每个实体的属性并显示它们。(例如,使用TextEntity的颜色和文本创建一个文本框) 一起管理这些实体感觉有点像黑客。如果每个实体都有

我正在使用MVVM模式在WPF中开发一个应用程序,遇到了一些可能有点独特的东西

我有一个抽象类
MapEntity
,它表示可以在应用程序的绘图表面上显示的实体。其他类,如
LineEntity
TextEntity
等,都是从
MapEntity
继承的

为了显示这些,我为每种类型创建了一个
ObservableCollection
,并将其绑定到我的XAML,该XAML获取每个实体的属性并显示它们。(例如,使用
TextEntity
的颜色和文本创建一个文本框)

一起管理这些实体感觉有点像黑客。如果每个实体都有一组集合,我可以创建一个
可观测集合
,并将所有实体添加到其中。这将使处理它们更容易,例如当用户拖动实体时检查它们的边界,或者通过
MapEntity
中定义的更新方法更新它们。标准继承的东西

使用此技术时会出现问题,是否有方法创建绑定到此单个集合的
ItemsControl
(而不是将每个
ItemsControl
绑定到
TextEntity
LineEntity
等集合),但只显示特定类型的元素

例如:

视图模型:

我想做:

<ItemsControl ItemsSource="{Binding Entities WHERE type = LineEntity}"> <!-- More Stuff -->  </ItemsControl>
 <ItemsControl ItemsSource="{Binding Entities WHERE type = TextEntity}"> <!-- More Stuff -->  </ItemsControl>

(显然无效),但基本上我只想从集合中“过滤”出所需的类型,通过不使用单独的集合,在ViewModel中更易于管理。(因此,必须在每台机器上分别运行操作)


我很确定这是不可能的,但我想如果有人有任何想法,我会问,无论是通过XAML还是ViewModel。

您可以看看这个类,并使用它的过滤功能对类型进行过滤


很好的一点是,它从您的基础ObservaleCollection传播集合更改事件。

您可以查看该类,并使用其过滤功能对类型进行过滤


很好的一点是,它从您的基础ObservableCollection传播集合更改事件。

您可能已经知道
ItemsControl
会根据每个项的类型自动选择正确的
ItemTemplate

为从MapEntity派生的每种类型定义一个空的DataTemplate,如下所示,以便任何
ItemsControl
(未明确设置其ItemTemplate)从这些资源中进行选择

<Window.Resources>
    <DataTemplate DataType="{x:Type vm:TextEntity}">
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:LineEntity}">
    </DataTemplate>
</Window.Resources>

现在您需要为每个ItemsControl重写其中一个

<ItemsControl ItemsSource="{Binding Entities}">
    <ItemsControl.Resources>
        <DataTemplate DataType="{x:Type vm:TextEntity}">
            <!-- Template for text entity -->
        </DataTemplate>
    </ItemsControl.Resources>
</ItemsControl>

您可能已经知道
项目控制
会根据每个项目的类型自动选择正确的
项目模板

为从MapEntity派生的每种类型定义一个空的DataTemplate,如下所示,以便任何
ItemsControl
(未明确设置其ItemTemplate)从这些资源中进行选择

<Window.Resources>
    <DataTemplate DataType="{x:Type vm:TextEntity}">
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:LineEntity}">
    </DataTemplate>
</Window.Resources>

现在您需要为每个ItemsControl重写其中一个

<ItemsControl ItemsSource="{Binding Entities}">
    <ItemsControl.Resources>
        <DataTemplate DataType="{x:Type vm:TextEntity}">
            <!-- Template for text entity -->
        </DataTemplate>
    </ItemsControl.Resources>
</ItemsControl>


谢谢,这太完美了!你知道如果不是
数据类型
,它是否正在为ItemControls创建一个“空白”元素,或者WPF会看到只定义了一个
数据模板
,而不会“尝试”将其添加到控件中吗?实际上我不确定,但我认为ItemsControl显示了一个虚拟文本(数据类型的完整命名空间和类名)。谢谢,这太完美了!您知道它是否正在为ItemControls if type type创建一个“空白”元素,如果不是
数据类型
,或者WPF会看到只定义了一个
数据模板
,而不必“尝试”吗要将它添加到控件中吗?实际上我不确定,但我认为ItemsControl在找不到合适的模板时会显示一个伪文本(数据类型的完整名称空间和类名)。