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>
如果没有Border后的Background绑定触发器就不能够直接设置背景颜色。
第二个是在ListBox的样式设置中,里面分成4个Style(这个以前写过了),然后在写ItemsPanel的样式中(这个就是在ListBox控件里面的子元素的布局容器),如果我需要后台设置或者动态的设置这个Panel里面的属性,那就需要用VisualTreeHelper这个本来用来查看可视化树的东西来进入里面去找我们需要的Panel。就下如下这样:
<Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <UniformGrid Background="{Binding BackgroundColor}"/> </ItemsPanelTemplate> </Setter.Value> </Setter>
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; }
这样就可以设置了,然后我把这两个问题写在一起写了个DEMO,就当总结吧:ListBoxDemo