我有一个Listbox,它基于相同的基类存储两种不同的对象类型。 (例如,BaseObject = baseclass及其子代:CustomPath和CustomImage)
数据源:
ObservableCollection<BattlegroundBaseObject> _baseObjectCollection;
public ObservableCollection<BattlegroundBaseObject> BaseObjectCollection
{
get { return _baseObjectCollection?? (_baseObjectCollection= new ObservableCollection<BaseObject>()); }
}
列表框数据绑定:<ListBox ItemsSource="{Binding BaseObjectCollection}"
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" x:Name="ListBoxPathLineStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem" x:Name="BattlegroundObjectControlTemplate">
<Path Stroke="{Binding ObjectColor}" StrokeThickness="{Binding StrokeThickness}" Data="{Binding PathGeometryData}" x:Name="PathLine" Opacity="{Binding Opacity}">
</Path>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Effect" TargetName="PathLine">
<Setter.Value>
<DropShadowEffect Color="CornflowerBlue" ShadowDepth="3" BlurRadius="10" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
我想添加到Path所在的ControlTemplate,也是一个Image,并根据类型或属性进行区分。没关系。
任何想法?
答案 0 :(得分:1)
您可以为每种类型添加ListBox
资源DataTemplate
。
在我的示例类Car
和Motorbike
派生自Vehicle
类。
<ListBox x:Name="listBox">
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:Car}">
<StackPanel Background="Red">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Motorbike}">
<StackPanel Background="Orange">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.Resources>
</ListBox>
修改强>
您可以将ListBoxItem
的样式添加到资源:
<ListBox x:Name="listBox">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect Color="CornflowerBlue" ShadowDepth="3" BlurRadius="10" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type local:Car}">
<StackPanel Background="Red">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Motorbike}">
<StackPanel Background="Orange">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.Resources>
</ListBox>
答案 1 :(得分:0)
您可以为不同的类定义一些DataTemplates。它们决定了类的显示方式。在处理基类的集合时,我一直在使用它们以不同的方式显示派生类。
<DataTemplate DataType="{x:Type CustomPath}">
<TextBlock Text="This is a CustomPath"/>
</DataTemplate>
<DataTemplate DataType="{x:Type CustomImage}">
<TextBlock Text="This is a CustomImage"/>
</DataTemplate>
答案 2 :(得分:0)
目前,您正在更改WPF用于呈现绑定数据的控件的样式。更好的方法是为WPF提供一种生成正确控件的方法。忽略ListBoxItem
并使用DataTemplate
s作为实际对象。
首先,你需要告诉窗口或控制如何找到你的类型。
<Window or UserControl
...
xmlns:model="clr-namespace:yourNamespace"
>
然后,您可以为WPF提供一种显示对象的方法,例如
<DataTemplate TargetType="{x:Type model:CustomPath}">
<Path Stroke="{Binding ObjectColor}" StrokeThickness="{Binding StrokeThickness}"
Data="{Binding PathGeometryData}" x:Name="PathLine" Opacity="{Binding Opacity}"/>
<!-- maybe use a binding from the Path.Effect back to the IsSelected and ValueConverters
to re-apply the selection effect-->
</DataTemplate>
<DataTemplate TargetType="{x:Type model:CustomImage}">
<Image Src="{Binding SomeProperty}" />
</DataTemplate>
现在您需要做的就是以某种方式使ListBox可用。几乎WPF中的每个元素都可以添加.Resources
,因此您可以选择在整个窗口中执行这些操作
<Window ...>
<Window.Resources>
<DataTemplate .../>
<DataTemplate .../>
</Window.Resources>
...
<ListBox .../>
</Window>
或者您可以在本地更多地应用
<Window ...>
...
<ListBox>
<ListBox.Resources>
<DataTemplate .../>
<DataTemplate .../>
</ListBox.Resources>
</ListBox>
</Window>
这样你的列表框定义也可以变得更整洁,例如如果您使用Window.Resources
<ListBox ItemsSource="{Binding BaseObjectCollection}"/>