在WPF代码隐藏中,我如何为每个单独的ListBoxItem设置背景颜色,其中颜色基于项本身



我的最终目标是让ListBox向我显示颜色列表,其中背景色的值就是颜色本身。最终,这个ListBox将加载以前保存的颜色集合,但现在我只是想让它使用伪数据——我使用System.Windows.Media.Colors中的颜色填充的字典(<string, Color>,其中string是友好名称,Color是一个自定义类,只包含颜色的RedGreenBlueHex值)。这样设置是因为用户存储的颜色最终只有一个名称(键)和RGB/Hex值。

通过将ItemsSource设置为App.SavedColors.Keys(其中SavedColors是前面提到的字典),我可以在ListBox中显示颜色的名称。我找到了一些答案,可以解释如果你知道自己想要什么颜色(即,如果"严重性"或某个值等于1,则为"绿色"),如何根据属性进行绑定,但也不能绑定颜色。

使用我在研究这一问题时发现的解决方案,我能够找出如何几乎使其发挥作用。但这段代码似乎只是根据最后一个项目的颜色为所有项的背景上色,所以我想这只是在每次创建新行时更改整体背景颜色。如何避免每次迭代都覆盖以前的背景?

到目前为止,我能使用的最接近的代码:

//Bind the saved colors.
ListBox_SavedColors.ItemsSource = App.SavedColors.Keys;
//Color the backgrounds.
for (int i = 0; i < ListBox_SavedColors.Items.Count; i++)
{
    //Create the blank style.
    Style styleBackground = new System.Windows.Style();
    styleBackground.TargetType = typeof(ListBoxItem);
    //Get the color and store it in a brush.
    Color color = App.SavedColors[ListBox_SavedColors.Items[i].ToString()];
    SolidColorBrush backgroundBrush = new SolidColorBrush();
    backgroundBrush.Color = System.Windows.Media.Color.FromRgb(color.Red, color.Green, color.Blue);
    //Create a background setter and add the brush to it.
    styleBackground.Setters.Add(new Setter
    {
        Property = ListBoxItem.BackgroundProperty,
        Value = backgroundBrush
    });
    ListBox_SavedColors.ItemContainerStyle = styleBackground;
}

代码的问题在于,您分配了影响所有ListBoxItems的相同属性ItemsContainerStyle。所以所有的物品都会有最后一个的颜色。

您的代码应该直接分配项目的背景。

for (int i = 0; i < ListBox_SavedColors.Items.Count; i++)
{
    //Get the color and store it in a brush.
    Color color = App.SavedColors[ListBox_SavedColors.Items[i].ToString()];
    SolidColorBrush backgroundBrush = new SolidColorBrush(color);
    ListBoxItem item = ListBox_SavedColors.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
    item.Background = backgroundBrush;
}

但作为彼得·汉森,最好使用XAML来解决这个问题。例如,您可以编写一个转换器,将ListBoxItem中的数据转换为SolidColorBrush。然后,您可以将项目的背景绑定到其内容。

public class ListBoxItemColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return new SolidColorBrush(App.SavedColors[value.ToString()]);
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

XAML将如下所示:

<ListBox x:Name="MyList">
    <ListBox.Resources>
        <local:ListBoxItemColorConverter x:Key="ListBoxItemColorConverter"/>
    </ListBox.Resources>
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Background" Value="{Binding Converter={StaticResource ListBoxItemColorConverter}}"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

最新更新