我有一个案例,其中一些人被分成几组,人和组来自数据库。我想将此数据显示为每个组的一系列ListBox,其中该组中的人员显示在ListBox中。我在每个组的代码中执行此操作,如下所示:
首先我定义一个ListBox
lbx = New ListBox
With lbx
.ContextMenu = cm
.DisplayMemberPath = "FullName"
.SelectedValuePath = "PersonID"
End With
然后我从数据库中填充一个ObservableCollection(Person),然后将该集合指定为ListBox的ItemsSource。
lbx.ItemsSource = ocGrouMembers
然后我将ListBox添加到我在XAML中定义的名为“pnl”的面板中。
pnl.Children.Add(lbx)
现在出现了问题:我想更改ListBoxes中某些人的演示文稿。首先,我以为我在XAML中使用TargetType = ListBoxItem定义了一个Style。但是这不起作用,因为在代码中我没有明确定义ListBoxItems所以没有办法为它们定义样式。
其次,我想过在XAML中创建一个DataTemplate,但据我所知,代码中没有办法将DataTemple直接应用于ListBoxes。
我希望这很清楚。在这种情况下,如何更改ListBox中名称的外观?
编辑:最终解决方案
我最终在XAML中定义了数据模板,如下所示:
<DataTemplate
DataType="ListBoxItem"
x:Key="dtpListBoxItem">
<TextBlock
x:Name="txtPerson"
Text="{Binding FullName}">
</TextBlock>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding Path=Chair}" Value="True">
<Setter TargetName="txtPerson" Property="Foreground" Value="Blue" />
<Setter TargetName="txtPerson" Property="FontWeight" Value="DemiBold" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
在代码中使用它如下:
lbx = New ListBox
With lbx
... other properties ....
.ItemTemplate = DirectCast(Resources("dtpListBoxItem"), DataTemplate)
End With
答案 0 :(得分:0)
正如评论中所提到的,使用MVVM是一种很好的做法,但请找一些解决方法。
您可以使用数据模板,并根据您可以设置的样式检查数据:
<DataTemplate DataType="{x:Type ListBoxItem}">
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Group}">
<DataTrigger.Value>
<src:Group>Group1</src:Group>
</DataTrigger.Value>
<DataTrigger.Setters>
<Setter Property="BorderBrush" Value="DodgerBlue" TargetName="border" />
<Setter Property="Foreground" Value="Navy" TargetName="descriptionTitle" />
<Setter Property="Foreground" Value="Navy" TargetName="currentPriceTitle" />
<Setter Property="BorderThickness" Value="3" TargetName="border" />
<Setter Property="Padding" Value="5" TargetName="border" />
</DataTrigger.Setters>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Group}">
<DataTrigger.Value>
<src:Group>Group2</src:Group>
</DataTrigger.Value>
<Setter Property="BorderBrush" Value="Orange" TargetName="border" />
<Setter Property="Foreground" Value="Navy" TargetName="descriptionTitle" />
<Setter Property="Foreground" Value="Navy" TargetName="currentPriceTitle" />
<Setter Property="Visibility" Value="Visible" TargetName="star" />
<Setter Property="BorderThickness" Value="3" TargetName="border" />
<Setter Property="Padding" Value="5" TargetName="border" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
一些链接:
datatemplates-and-datatriggers-in-wpf
动态应用数据模板:
ListBox dynamictemplatelistBox = new ListBox();
//dynamictemplatelistBox.DisplayMemberPath = "Name"; /// we cant set template and displaymember at same time.
dynamictemplatelistBox.ItemsSource = list;
string xamlTemplate = "<DataTemplate DataType=\"{x:Type ListBoxItem}\">"
+ "<TextBlock x:Name=\"txt1\" Text=\"{Binding Name}\" />"
+ "<DataTemplate.Triggers>"
+ "<DataTrigger Binding=\"{Binding Path=Name}\" Value=\"test\">"
+ "<Setter TargetName=\"txt1\" Property=\"Background\" Value=\"Yellow\" />"
+ "</DataTrigger>"
+ "</DataTemplate.Triggers>"
+ "</DataTemplate>";
var xaml = xamlTemplate; // String.Format(xamlTemplate, "ListBoxItem");
var context = new ParserContext();
context.XamlTypeMapper = new XamlTypeMapper(new string[0]);
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
var template = (DataTemplate)XamlReader.Parse(xaml, context);
//dynamictemplatelistBox.Template = template;
dynamictemplatelistBox.ItemTemplate = template;
parentStackPanel.Children.Add(dynamictemplatelistBox);
或者您可以在XAMl中定义样式并从代码中动态设置:
dynamictemplatelistBox.ItemTemplate = this.Resources["testCodeBehindtemplate"] as DataTemplate;