WPF ListBox

记录一些ListBox的用法

1.设置ListBox选中项的背景颜色

  • 采用模板

先看一下效果图:

在设置listbox选中样式是遇到一个问题:选中项的背景设置不起作用

经过一段时间的挣扎后找到原因,模板里的控件要设置 Background="{TemplateBinding Background}" TextBlock.Foreground="{TemplateBinding Foreground}"否则背景是不会变化的。

<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>
设置中间列有效果

 

<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>
设置整个ListBoxItem有效果

里面我用到的布局控件为“Grid”简单点的还可以用“Border”等控件。

  • 自定义SystemColors类的参数

SystemColors的HighlightBrushKey和HighlightTextBrushKey分别代表ListBoxItem被选中时文字和背景颜色,没有Highlight的BrushKey代表ListBox没有焦点时的选中项文字和背景颜色。

 效果图:

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

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

3.连续选择同一项时SelectionChanged 事件不响应的问题

  • 简单点的方式

处理SelectionChanged当操作结束后把SelectedIndex设为-1;

private void lBox_SelectionChanged(object sender, SelectionChangedEventArgs e)  
{  
    if (lBox.SelectedIndex == -1) 
    {    
        return;  
    }
    // 这里填写所需要处理的代码
    lBox.SelectedIndex = -1;              
}
View Code
  • 复杂点就是重载OnSelect()

这不局限与ListBox,TreeView等都可以参考

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);
        }
    }
View Code

这是我在一个博客上转载的,不过当时放在有道云笔记中,作者的地址已经丢失,在此对这位博主表示歉意。

posted @ 2015-07-31 14:46  MartialWorldFish  阅读(765)  评论(0编辑  收藏  举报