WPF关于改变ListBoxItem的颜色的注意事项以及如何找到ListBox中的ItemsPanel

在ListBox中碰到过几个问题,现在把它写出来:

第一个就是在ListBoxItem中当我用触发器IsSelected和IsMouseOver来设置Background和Foreground的时候,Foreground是可以直接设置的,但是Background的颜色是不会改变的。网上查了下貌似是需要手动更改ListBoxItem的控件模板让其直接使用ListBoxItem的Background属性。如下:

<Style x:Key="itemtemplate" TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border BorderThickness="2" BorderBrush="Red" Background="{TemplateBinding Background}">
                            <ContentPresenter TextBlock.Foreground="{TemplateBinding Foreground}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>

            <Style.Triggers>
                <Trigger Property="IsSelected" Value="true">
                    <Setter Property="Background" Value="Gray"/>
                    <Setter Property="Foreground" Value="White"/>
                </Trigger>
                <Trigger Property="IsMouseOver" Value="true">
                    <Setter Property="Background" Value="LightGreen"/>
                    <Setter Property="Foreground" Value="Red"/>
                </Trigger>
            </Style.Triggers>
        </Style>
View Code

如果没有Border后的Background绑定触发器就不能够直接设置背景颜色。

第二个是在ListBox的样式设置中,里面分成4个Style(这个以前写过了),然后在写ItemsPanel的样式中(这个就是在ListBox控件里面的子元素的布局容器),如果我需要后台设置或者动态的设置这个Panel里面的属性,那就需要用VisualTreeHelper这个本来用来查看可视化树的东西来进入里面去找我们需要的Panel。就下如下这样:

<Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <UniformGrid Background="{Binding BackgroundColor}"/>
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
View Code
private void Button_Click(object sender, RoutedEventArgs e) {
            UniformGrid uniformGrid = GetVisualChild<UniformGrid>(listBox);
            uniformGrid.Background = Brushes.Black;
        }

        public static T GetVisualChild<T>(object parent) where T : Visual {
            DependencyObject dependencyObject = parent as DependencyObject;
            return InternalGetVisualChild<T>(dependencyObject);
        }

        private static T InternalGetVisualChild<T>(DependencyObject parent) where T : Visual {
            T child = default(T);

            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numVisuals; i++) {
                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                child = v as T;
                if (child == null) {
                    child = GetVisualChild<T>(v);
                }
                if (child != null) {
                    break;
                }
            }
            return child;
        }
View Code

这样就可以设置了,然后我把这两个问题写在一起写了个DEMO,就当总结吧:ListBoxDemo

原文地址:https://www.cnblogs.com/socialdk/p/3145257.html