我想将ItemsCollection数据绑定,但不想渲染集合项,而是想渲染通过集合项属性访问的子对象。
更具体地说:这是一个用于游戏的2D地图查看器(虽然它现在还不是2D)。我将ItemsControl数据绑定到ObservableCollection<Square>,其中Square有一个名为Terrain(类型为Terrain)的属性。Terrain是一个基类,具有各种后代。
我希望ItemsControl从每个集合元素中呈现Terrain属性,而不是集合元素本身。
我已经可以实现这一点,但有些不必要的开销。我想知道是否有一种好的方法来消除这些不必要的��销。
我当前拥有以下简化的类:
public class Terrain {}
public class Dirt : Terrain {}
public class SteelPlate : Terrain {}
public class Square
{
public Square(Terrain terrain)
{
Terrain = terrain;
}
public Terrain Terrain { get; private set; }
// additional properties not relevant here
}
有一个名为MapView的UserControl,包含以下内容:
<UserControl.Resources>
<DataTemplate DataType="{x:Type TerrainDataModels:Square}">
<ContentControl Content="{Binding Path=Terrain}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type TerrainDataModels:Dirt}">
<Canvas Width="40" Height="40" Background="Tan"/>
</DataTemplate>
<DataTemplate DataType="{x:Type TerrainDataModels:SteelPlate}">
<Canvas Width="40" Height="40" Background="Silver"/>
</DataTemplate>
</UserControl.Resources>
<ItemsControl ItemsSource="{Binding}"/>
如果我运行以下代码:
mapView.DataContext = new ObservableCollection<Square> {
new Square(new Dirt()),
new Square(new SteelPlate())
};
我得到了一些看起来与我的预期完全相同的东西:一个包含棕色盒子(表示土)和银色盒子(表示钢板)的 StackPanel。但是我获得它时存在一些不必要的开销。
我特别关注的是我针对 Square 的 DataTemplate:
<DataTemplate DataType="{x:Type TerrainDataModels:Square}">
<ContentControl Content="{Binding Path=Terrain}"/>
</DataTemplate>
我想要表达的是“不需要渲染Square本身,而是直接渲染其Terrain属性”。这个方法接近于实现需求,但对于每个Square,会在可视树中增加额外的两个控件:ContentControl(如上XAML所示)和它的ContentPresenter。我并不需要ContentControl,我真正想要的是插入Terrain属性的DataTemplate作为控件树的一部分。但是如何告诉ItemsControl渲染collectionitem.Terrain(查找以上DataTemplates中的一个Terrains对象的模板),而不是渲染collectionitem(查找Square对象的DataTemplate)?
我想使用terrains的DataTemplates,但不一定要用于Square - 这只是我找到的第一个有效方法。实际上,我真正想做的是完全不同的事情 - 我真正想做的是将ItemsControl的DisplayMemberPath设置为“Terrain”。这将直接呈现正确的对象(Dirt或SteelPlate对象),而无需添加额外的ContentControl或ContentPresenter。不幸的是,DisplayMemberPath始终呈现字符串,忽略了terrains的DataTemplates。因此,它有正确的想法,但对我来说是无用的。
这整个过程可能是过早进行优化,如果没有容易实现的方法,我可以接受目前的结果。但如果有我尚未了解的“WPF方式”来绑定属性而不是整个集合项,那将增加我对WPF的理解,这正是我追求的。