• ListBox复选框拓展


    Toolkit的LongListMutiSelector的复选框功能,想必许多人都需要吧!然而系统本身控件ListBox虽然也有多选功能,可是外观上却缺乏复选框,选择效果只是颜色变化。于是在上一个项目中只好选择LongListMutiSeletor作为列表的控件,项目结束后就有个想法对ListBox进行拓展,使ListBox列表可以拥有复选框。

    之前为了修改LongListMutiSelector在白色背景下滚动条无法显示的问题,曾经仔细看了一下LongListMutiSelector相关的一些模版,发现LongListMutiSelector的复选框其实来自LongListMutiSelectorItem模版中的Checkbox。于是心中就有个想法,对ListBox的模版进行修改添加上Checkbox,然后再绑定上ListBox本身IsSelected属性,这样就可以实现复选框了。

    说做就做,首先对模版进行拓展,添加Checkbox。

    <Style TargetType="control:ListBoxItemEx">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="control:ListBoxItemEx">
                        <Border x:Name="LayoutRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver"/>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentContainer"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Unselected"/>
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <!--<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>-->
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates"/>
                            </VisualStateManager.VisualStateGroups>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <CheckBox x:Name="checkBox" Grid.Column="0" IsChecked="{TemplateBinding IsSelected}" Visibility="Collapsed"/>
                                <ContentControl x:Name="ContentContainer" Grid.Column="1" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Grid>                       
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

     其次,再对ListBox进行继承拓展。增加SelectionEable属性,当属性更改显示或隐藏复选框。

     public ItemSelectionMode SelectionEable
            {
                get { return (ItemSelectionMode)GetValue(SelectionEableProperty); }
                set { SetValue(SelectionEableProperty, value); }
            }
    
            public static readonly DependencyProperty SelectionEableProperty = DependencyProperty.Register(
                "SelectionEable",
                typeof(ItemSelectionMode),
                typeof(ListBoxItemEx),
                new PropertyMetadata(ItemSelectionMode.Normal, OnSelectionEableChanged));
    
            private static void OnSelectionEableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                ListBoxItemEx item = d as ListBoxItemEx;
                if (item.checkBox != null)
                {
                    ItemSelectionMode mode = (ItemSelectionMode)e.NewValue;
                    switch (mode)
                    {
                        case ItemSelectionMode.Normal:
                            item.checkBox.Visibility = Visibility.Collapsed;
                            break;
                        case ItemSelectionMode.Selection:
                            item.checkBox.Visibility = Visibility.Visible;
                            break;
                    }
                }
            }

    Ok在页面前台写下以下代码,就会发现设计视图中的ListBoxItem有了复选框。

    <MyControls:ListBoxItemEx SelectionEable="Selection">
                测试选项
            </MyControls:ListBoxItemEx>

    拓展完ListBoxItem后事情还没完,这只是ListBoxItem有了复选框,ListBox并没有,还要对ListBox进行拓展才行。

    同样拓展一个SlectionEable属性,并且将该属性和它的Item的SelectonEable属性关联起来。其次还得重载ListBox的GetContainerForItemOverride方法,返回一个重载后的ListBoxItemEx对象作为列表生产每一项内容的承载容器。这样就完成了对ListBox复选框的拓展。

    ps:实际测试中发现复选框的IsChecked属性和ListBoxItem的IsSelected属性并没有同步,后面仔细查看文档后发现TemplateBinding并不能进行双向绑定,即前台Checkbox的勾选变化不会同步到IsSelected属性,而只有Binding和StaticResource可以进行双向绑定,于是将TemplateBinding改为Binding,Mode为TwoWay,这样就可以双向绑定了。

  • 相关阅读:
    Chapter 7、面向对象(二)---类 (4th,Mar.)
    Chapter 7、面向对象(一)--- 概述
    值类型,引用类型
    Chapter 6、字符串(二)(1st,Mar.)
    练习:判断字符串“mingrikejijavabu”中,字符“i”出现了几次,并将结果输出。
    函数对象
    顺序容器:双向链表 list
    顺序容器:vector和deque 的程序举栗子
    STL中的 “大”、“小”和 “相等”
    标准模板库STL中常用的算法
  • 原文地址:https://www.cnblogs.com/qingfengwutong/p/3318410.html
Copyright © 2020-2023  润新知