如何在代码中将样式应用于ListBox

时间:2018-03-12 19:28:25

标签: wpf listbox

我有一个案例,其中一些人被分成几组,人和组来自数据库。我想将此数据显示为每个组的一系列ListBox,其中该组中的人员显示在ListBox中。我在每个组的代码中执行此操作,如下所示:

  1. 首先我定义一个ListBox

    lbx = New ListBox
    With lbx
       .ContextMenu = cm
       .DisplayMemberPath = "FullName"
       .SelectedValuePath = "PersonID"
    End With
    
  2. 然后我从数据库中填充一个ObservableCollection(Person),然后将该集合指定为ListBox的ItemsSource。

    lbx.ItemsSource = ocGrouMembers
    
  3. 然后我将ListBox添加到我在XAML中定义的名为“pnl”的面板中。

    pnl.Children.Add(lbx)
    
  4. 现在出现了问题:我想更改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
    

1 个答案:

答案 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>

一些链接:

datatemplate

Data-Binding-Demo-

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;