【问题标题】:Changing a <Type> Listbox backcolor更改 <Type> 列表框背景颜色
【发布时间】:2014-04-15 14:59:38
【问题描述】:

我有一个包含客户类型列表的列表框。所以我的 Listbox.Items 不再是 ListItem 类型,而是 customer 类型。

我在客户字段中有一个 isActive 标志,我想知道如果 isActive 为真,我将如何将背景颜色设置为红色。

目前我已经尝试过了,但它不起作用,因为我无法让客户输入 ListBoxtem

            List<object> inactiveCustomers = new List<object>();
        foreach (Customer item in ListBoxCustomers.Items)
        {
            if (!item.IsActive)
            {
                inactiveCustomers.Add(item);
                int index = ListBoxCustomers.Items.IndexOf(item);
                ListBoxItem x = (ListBoxItem)ListBoxCustomers.Items[index];
                x.Background = Brushes.Red;
            }
        }

编辑: 每当我取消选择适用于活跃客户的复选框时,我都会调用一个执行上述代码的方法。每当我取消选中 Active Checkbox 时,我都会遍历客户并显示所有客户,此时我想更改非活动的背景颜色以区分哪些是非活动/活动的

【问题讨论】:

    标签: c# wpf listbox


    【解决方案1】:

    有两种方法可以做到这一点。 “正确”的 WPF 方式是在 XAML 中完成所有操作:

    <ListBox x:Name="ListBoxCustomers" ItemsSource="{Binding Customers}">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsActive}" Value="False">
                        <Setter Property="Background" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    

    在代码隐藏中执行此操作的 WinForms 样式方法需要从列表框中获取容器。但是,由于 UI 虚拟化,并非所有必需的项目都有容器。因此,此代码只会更改当前可见项目的容器。如果 ListBox 被滚动,新项目可能有也可能没有您期望的设置(取决于回收规则)。

    List<object> inactiveCustomers = new List<object>();
    foreach (Customer item in ListBoxCustomers.Items)
    {
        if (!item.IsActive)
        {
            inactiveCustomers.Add(item);
            var container =  ListBoxCustomers.ItemContainerGenerator.ContainerFromItem(item) as ListBoxItem;
            if (container != null)
                container.Background = Brushes.Red;
        }
    }
    

    【讨论】:

    • 感谢 wpf 示例,它运行良好!非常感谢。
    【解决方案2】:

    要获取ListBoxItem,您可以使用ListBoxItemContainerGenerator。确保在加载完成后执行此操作,例如在 Loaded 事件处理程序中,因为加载前控件尚不存在。

    void Window_Loaded(object sender, RoutedEventArgs e)
    {
        List<object> inactiveCustomers = new List<object>();
        foreach (Customer item in ListBoxCustomers.Items)
        {
            if (!item.IsActive)
            {
                inactiveCustomers.Add(item);
                ListBoxItem x = ListBoxCustomers.ItemContainerGenerator.ContainerFromItem(item) as ListBoxItem;
                if (x != null)
                    x.Background = Brushes.Red;
            }
        }
    }
    

    【讨论】:

    • 它设法解析它,所以这是一个加号,但是,x 现在为空。所以它永远不会设置背景。
    • 确保在 ListBox 加载了分配的数据后运行它。我以 Window.Loaded 为例,但您在加载数据时可能进行了不同的设置。
    • 除了预加载时间之外,许多 WPF ItemsControl 子类(列表 ListBox)利用 UI 虚拟化,这可以防止 UI 为屏幕外的项目创建一堆内存中的 UIElement。这是 ContainerFromItem/ContainerFromIndex 返回 null 的另一种情况。这是在 XAML 中完成这一切的一个很好的理由。如果您在代码隐藏中执行所有这些操作,则必须手动检测 ItemContainerGenerator 何时创建新项目并手动应用设置。
    • 我应该在 OP 中提到这一点,当表单加载时,它很好,因为它只显示所有活动客户。但是我有一个复选框来显示所有客户,然后我选择这个我想显示每个客户,那些不活跃的客户将有不同的背景颜色。所以我的 ChangeColorOfInactiveCustomer() 方法是在窗口加载后被调用的。
    猜你喜欢
    • 2012-10-23
    • 2012-10-20
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    相关资源
    最近更新 更多