记录一些ListBox的用法
- 设置ListBox选中项的背景颜色
- 如何为标准的ListBox添加ItemClick事件
- 连续选择同一项时SelectionChanged 事件不响应的问题
1.设置ListBox选中项的背景颜色
- 采用模板
先看一下效果图:
在设置listbox选中样式是遇到一个问题:选中项的背景设置不起作用
经过一段时间的挣扎后找到原因,模板里的控件要设置 Background="{TemplateBinding Background}" TextBlock.Foreground="{TemplateBinding Foreground}"否则背景是不会变化的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<ListBox Name="list" ItemsSource="{Binding InfoList}"> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <!-- 设置控件模板 --> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="20"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="auto"/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Num}" Grid.Column="0"/> <TextBlock Text="{Binding Name}" Grid.Column="1" Background="{TemplateBinding Background}" TextBlock.Foreground="{TemplateBinding Foreground}"/> <TextBlock Text="{Binding Sex}" Grid.Column="2"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> <!-- 设置触发器 --> <Style.Triggers> <Trigger Property="IsSelected" Value="true"> <Setter Property="Background" Value="#64BCEA"/> </Trigger> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Background" Value="#C7DEEA"/> <!--<Setter Property="Foreground" Value="Red"/>--> </Trigger> </Style.Triggers> </Style> </ListBox.ItemContainerStyle> </ListBox>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<ListBox Name="list" ItemsSource="{Binding InfoList}"> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <!-- 设置控件模板 --> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <Grid Background="{TemplateBinding Background}" TextBlock.Foreground="{TemplateBinding Foreground}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="20"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="auto"/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Num}" Grid.Column="0"/> <TextBlock Text="{Binding Name}" Grid.Column="1"/> <TextBlock Text="{Binding Sex}" Grid.Column="2"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> <!-- 设置触发器 --> <Style.Triggers> <Trigger Property="IsSelected" Value="true"> <Setter Property="Background" Value="#64BCEA"/> </Trigger> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Background" Value="#C7DEEA"/> <!--<Setter Property="Foreground" Value="Red"/>--> </Trigger> </Style.Triggers> </Style> </ListBox.ItemContainerStyle> </ListBox>
里面我用到的布局控件为“Grid”简单点的还可以用“Border”等控件。
- 自定义SystemColors类的参数
SystemColors的HighlightBrushKey和HighlightTextBrushKey分别代表ListBoxItem被选中时文字和背景颜色,没有Highlight的BrushKey代表ListBox没有焦点时的选中项文字和背景颜色。
效果图:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<ListBox> <ListBox.Resources> <Style TargetType="ListBoxItem"> <Style.Resources> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Pink"/> <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Gray"/> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Red"/> <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Green"/> </Style.Resources> </Style> </ListBox.Resources> <ListBoxItem>AAA</ListBoxItem> <ListBoxItem>B</ListBoxItem> <ListBoxItem>ccc</ListBoxItem> </ListBox>
这是在网上其他人的博客里看到的,我没有详细去做。
2.如何为标准的ListBox添加ItemClick事件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class MyListBox:ListBox { private static readonly object EventItemClick = new object(); public event EventHandler<ListBoxItemEventArgs> ItemClick { add { Events.AddHandler(EventItemClick, value); } remove { Events.RemoveHandler(EventItemClick, value); } } protected virtual void OnItemClick(ListBoxItemEventArgs e) { EventHandler<ListBoxItemEventArgs> handler = (EventHandler<ListBoxItemEventArgs>)this.Events[EventItemClick]; if (handler != null) { handler(this, e); } } protected override void OnClick(EventArgs e) { base.OnClick(e); for (int i = 0; i < this.Items.Count; i++) { bool flag = this.GetItemRectangle(i).Contains(this.PointToClient(Control.MousePosition)); if (flag) { ListBoxItemEventArgs args = new ListBoxItemEventArgs(i); OnItemClick(args); break; } } } } public class ListBoxItemEventArgs : EventArgs { private int _listBoxItem; public ListBoxItemEventArgs(int listBoxItem) { _listBoxItem = listBoxItem; } public int ListBoxItem { get { return _listBoxItem; } } }
3.连续选择同一项时SelectionChanged 事件不响应的问题
- 简单点的方式
处理SelectionChanged当操作结束后把SelectedIndex设为-1;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
private void lBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (lBox.SelectedIndex == -1) { return; } // 这里填写所需要处理的代码 lBox.SelectedIndex = -1; }
- 复杂点就是重载OnSelect()
这不局限与ListBox,TreeView等都可以参考
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class myListBox : System.Windows.Controls.ListBox { protected override DependencyObject GetContainerForItemOverride() { return new myListBoxItem(); } } public class myListBoxItem : System.Windows.Controls.ListBoxItem { protected override void OnSelected(System.Windows.RoutedEventArgs e) { DependencyObject dep = (DependencyObject)e.OriginalSource; while ((dep != null) && !(dep is ListBoxItem)) { dep = VisualTreeHelper.GetParent(dep); } if (dep == null) return; ListBoxItem item = (ListBoxItem)dep; if (item.IsSelected) { item.IsSelected = !item.IsSelected; //e.Handled = true; } base.OnSelected(e); } }
这是我在一个博客上转载的,不过当时放在有道云笔记中,作者的地址已经丢失,在此对这位博主表示歉意。