【问题标题】:Changing WPF Listbox SelectedItem text color and highlight/background Color using C#使用 C# 更改 WPF 列表框 SelectedItem 文本颜色和突出显示/背景颜色
【发布时间】:2015-04-25 13:00:43
【问题描述】:

我正在尝试在运行时更改 wpf 列表框的突出显示(选定)颜色和突出显示的文本颜色。我尝试创建一个样式并按如下方式应用它:

    Style s = new Style(typeof(ListBox));
    s.Resources.Add(SystemColors.HighlightBrushKey, Setting.ListSelectedColor);
    s.Resources.Add(SystemColors.HighlightTextBrushKey, Setting.ListSelectedTextColor);
    lstGames.Style = s;

但这似乎无济于事。有什么方法可以实现吗?

编辑:

根据建议,我尝试使用 DynamicResources 来实现这一点,但到目前为止这也没有成功。我的代码:

动态资源

<UserControl.Resources>
    <Color x:Key="ListTextSelectedColor"/>
    <Color x:Key="ListSelectedColor"/>
</UserControl.Resources>

列表框

        <ListBox ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" 
             Name="lstGames" Margin="20" Grid.Row="2" Grid.Column="2" 
             SelectionChanged="lstGames_SelectionChanged" Grid.RowSpan="2" Grid.ColumnSpan="2" 
             Background="{x:Null}" BorderBrush="{x:Null}" SelectionMode="Single"
             FontSize="18" FontFamily="OCR A Extended">
        <Style TargetType="ListBox">
            <Style.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{DynamicResource ListSelectedColor}"/>
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{DynamicResource ListSelectedColor}"/>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="{DynamicResource ListTextSelectedColor}"/>
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="{DynamicResource ListTextSelectedColor}"/>
            </Style.Resources>
        </Style>
    </ListBox>

在 C# 中应用资源

this.Resources["ListSelectedColor"] = SETING.ListSelectedColor.Color;
this.Resources["ListTextSelectedColor"] = SETTING.ListSelectedTextColor.Color;

【问题讨论】:

  • 我认为您正在寻找与 DynamicResource 的 xaml 绑定。有关示例,请参阅此 SO 问题。 stackoverflow.com/q/17502467/1862333
  • @failedprogramming 我曾尝试使用 DynamicResources 来实现这一点,但没有任何成功。我已经用我的尝试更新了我原来的帖子。
  • @failedprogramming 您的回答结合了我的运行状况。我会在我的最终解决方案中为其他人添加答案。

标签: c# wpf listbox


【解决方案1】:

解决方案:

<Window x:Class="ListBoxStyle.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:src="clr-namespace:ListBoxStyle"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style x:Key="_ListBoxItemStyle" TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border Name="_Border"
                                Padding="2"
                                SnapsToDevicePixels="true">
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter TargetName="_Border" Property="Background" Value="Yellow"/>
                                <Setter Property="Foreground" Value="Red"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <ListBox ItemContainerStyle="{DynamicResource _ListBoxItemStyle}"
                 Width="200" Height="250"
                 ScrollViewer.VerticalScrollBarVisibility="Auto"
                 ScrollViewer.HorizontalScrollBarVisibility="Auto">
            <ListBoxItem>Hello</ListBoxItem>
            <ListBoxItem>Hi</ListBoxItem>
        </ListBox>
    </Grid>
</Window>

【讨论】:

  • 谢谢你,但我意识到我实际上不想设置背景和前景属性,而是设置 HighlightBrushKey 和 HighlightBrushTextKey。动态资源似乎并没有以任何一种方式应用。有什么方法可以让我改变它们吗?
  • 经过一些操作后效果很好。我使用我当前的动态资源作为触发器设置器的值,之后它工作得很好。非常感谢!
【解决方案2】:

多亏了 Vinkal 和失败的编程,我让一切正常工作。我创建了以下资源:

<UserControl.Resources>
        <SolidColorBrush x:Key="ListTextSelectedColor" x:Shared="False"/>
        <SolidColorBrush x:Key="ListSelectedColor" x:Shared="False"/>
        <Style x:Key="_ListBoxItemStyle" TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border Name="_Border"
                                Padding="2"
                                SnapsToDevicePixels="true">
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter TargetName="_Border" Property="Background" Value="{DynamicResource ResourceKey=ListSelectedColor}"/>
                                <Setter Property="Foreground" Value="{DynamicResource ResourceKey=ListTextSelectedColor}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

然后将样式应用到我的列表框:

ItemContainerStyle="{DynamicResource ResourceKey=_ListBoxItemStyle}"

最后,通过执行以下操作更改我的 C# 代码中的solidcolorbrush 资源(因此更改设置器值):

    this.Resources["ListSelectedColor"] = EmulatorPage.ListSelectedColor;
    this.Resources["ListTextSelectedColor"] = EmulatorPage.ListSelectedTextColor;

谢谢你们俩!

【讨论】:

    【解决方案3】:

    致所有的邻居...不要失去希望! 可以做到

    我从 VSS 开始,右键单击列表框,并为每个可用的东西使用每个“编辑模板”和“编辑附加模板”,直到我发现这些东西是如何工作的。

    你从一个列表框开始,像往常一样绑定到 MVVM。

    <ListBox Width="100"
        x:Name="myComboBox" Margin="8"
        ItemsSource="{Binding ListBoxListSource}"
        SelectedIndex="{Binding ListBox}">
    </ListBox>
    

    在 UserControl 或 Window Resources 中设置一些东西......

    ListBoxStyle - 设置列表框主容器的样式,您可以在此处设置主框的边框、边距、内边距等。在我的示例中,我只是摆脱了一切以取消样式。

    <UserControl.Resources>
        <Style x:Key="ListBoxStyle" TargetType="{x:Type ListBox}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Foreground" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="Margin" Value="0"/>
        </Style>
    </UserControl.Resources>
    

    ItemContainerStyle - This is the bit that people say can't be re-styled - it contains the "windows-selector-blue" bar when an item is selected, but fear not this too can重新设置样式(将此 UserControl.Resources 部分与上述部分合并)。

    本节是> 将 ItemContainer 的模板从它的任何内容更改为 Border,将上边距设置为 3 以填充内容并设置样式。我们对这种样式所做的只是在项目的左侧和右侧添加 3px 透明边框。然后在 Triggers>IsSelected(myBorder 的目标)中,将边框 Brush 改为 Red。

    <UserControl.Resources>
        <Style x:Key="ItemContainerStyle" TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border x:Name="myBorder"
                                        Padding="0" Margin="0 3 0 0"
                                        SnapsToDevicePixels="true"
                                         Style="{DynamicResource borderContent}">
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Resources>
                            <Style x:Key="borderContent" TargetType="Border">
                                <Setter Property="BorderThickness" Value="3 0 3 0"/>
                                <Setter Property="BorderBrush" Value="Transparent"/>
                            </Style>
                        </ControlTemplate.Resources>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter TargetName="myBorder" Property="BorderBrush" Value="Red"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
    

    ListBoxItemDataTemplate - 下一步是制作显示数据的项目容器。在我的示例中,YourTextBlockStyler 在 Text>binding 上有一个触发器,并更改了文本的前景色和背景色。请注意,Listbox 样式的前景和背景设置为透明,因此如果您想看到任何内容,您必须在 TextBlock 样式中覆盖它们。

    <UserControl.Resources>
        <DataTemplate x:Key="ListBoxItemDataTemplate">
            <TextBlock Text="{Binding}" Style="{StaticResource YourTextBlockStyler}"/>
        </DataTemplate>
    </UserControl.Resources>
    

    返回列表框 - 现在我们已经在资源部分设置了所有样式和模板,我们可以使用 Style="" ItemContainerStyle="" 和 ItemTemplate=""

    <ListBox Width="100"
        x:Name="myComboBox" Margin="8"
        ItemsSource="{Binding ListBoxListSource}"
        SelectedIndex="{Binding ListBox}"
        Style="{StaticResource ListBoxStyle}"
        ItemContainerStyle="{StaticResource ItemContainerStyle}"
        ItemTemplate="{StaticResource ListBoxItemDataTemplate}">
    </ListBox>
    

    然后你无聊的列表框会神奇地变成一个带有红色边框选择器的完全重新设计的列表框

    无需编辑单个 System.ResourceBrush =]

    【讨论】:

      猜你喜欢
      • 2013-01-15
      • 2018-12-25
      • 1970-01-01
      • 2018-04-14
      • 2010-09-29
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 2017-07-11
      相关资源
      最近更新 更多