在WPF代码隐藏中,如何为每个单独的ListBoxItem设置背景颜色,其中颜色是基于项目本身? [英] In WPF code-behind, how do I set the background color for each individual ListBoxItem where the color is based on the item itself?

查看:2885
本文介绍了在WPF代码隐藏中,如何为每个单独的ListBoxItem设置背景颜色,其中颜色是基于项目本身?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的最终目标是让一个 ListBox 显示一个颜色列表,其中背景颜色的值是颜色本身。最终,这个 ListBox 将加载以前保存的颜色集合,但现在我只是想让它使用虚拟数据 - 一个字典,我填充使用颜色 System.Windows.Media.Colors < string,Color> ,其中字符串是友好名称, Color 是一个只包含 Red Green Blue Hex 。它是这样设置的,因为用户存储的颜色将最终只有一个名称(键)和RGB /十六进制值。

My end goal is to have a ListBox show me a list of colors, where the value of the background color is the color itself. Eventually, this ListBox will load a previously saved collection of colors, but for now I'm just trying to get it to work with dummy data - a dictionary I filled up using the colors from System.Windows.Media.Colors (<string, Color>, where string is the friendly name and Color is a custom class that only contains the Red, Green, Blue, and Hex values for the color). It's set up this way because the user-stored colors will eventually just have a name (the key), and RGB/Hex values.

我没有问题,的颜色通过其 ItemsSource 设置到 App.SavedColors的设置显示在 ListBox (其中 SavedColors 是前面提到的字典)。我发现一些答案,可以解释如何做的基于一个属性,如果你知道你想要什么颜色(即绿色如果严重性或某事等于1),但没有绑定的颜色。

I have no problem getting the names of the colors to show up in the ListBox by settings its ItemsSource to App.SavedColors.Keys (where SavedColors is the previously mentioned dictionary). And I found some answers that could explain how to do it based off of a property if you knew what colors you wanted (i.e. "green" if "severity" or something was equal to 1), but nothing for binding the color as well.

使用我在试图研究这个问题时发现的解决方案,我能够找出如何几乎使其工作。但似乎这个代码只是颜色的所有项目的背景,根据最后项目的颜色,所以我想象这只是改变整体的背景颜色每次将创建一个新行。

Using a solution I found while trying to research this, I was able to figure out how to almost make it work. But it seems like this code just colors the backgrounds of all the items, according to the color of the last item, so I imagine this just changes the overall background color every time a new row is created. How do I keep each iteration from overwriting the previous background?

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

The closest code I've been able to use so far:

//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。

The problem with your code is that you assign the same property ItemsContainerStyle that impacts all of the ListBoxItems. So all of the items will have the color of the last one.

您的代码应直接指定项目的背景。

Your code should directly assign the Background of the items.

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;
}

但是Peter Hansen最好使用XAML来解决这个问题。例如,你可以编写一个转换器,将ListBoxItem中的数据转换为SolidColorBrush。然后你可以将一个项目的背景绑定到它的内容。

But as Peter Hansen it is better to use a XAML to solve this problem. For exemple you can write a converter that will convert the data in the ListBoxItem into a SolidColorBrush. Then you can bind the background of an item to its content.

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将如下所示:

XAML will look like this:

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

这篇关于在WPF代码隐藏中,如何为每个单独的ListBoxItem设置背景颜色,其中颜色是基于项目本身?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆