天天看点

WPF 自定义多选ComboBox控件1.样式设计2.后台代码

自定会多选ComboBox控件

  • 1.样式设计
  • 2.后台代码

1.样式设计

采用ListBox控件,惊醒多选,然后对ListBox的ListBoxItem样式进行重新修改,增加CheckBox进行勾选显示

<!-- listbox 复选模式样式 -->
    <Style x:Key="ListBoxCheckBoxItemStayle" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border x:Name="border">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto"/>
                                <ColumnDefinition Width="1*"/>
                            </Grid.ColumnDefinitions>
                            <CheckBox Grid.Column="0" IsChecked="{Binding IsSelected,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"/>
                            <TextBlock Grid.Column="1" Text="{TemplateBinding Content}"/>
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Background" TargetName="border" Value="{StaticResource ComboBox.MouseOver.Background}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">
        <Grid x:Name="templateRoot" SnapsToDevicePixels="true">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
            </Grid.ColumnDefinitions>
            <Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
                <Themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}">
                    <Border x:Name="dropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
                        <ListBox x:Name="PART_ListBox" SelectionMode="Multiple" ItemsSource="{Binding ItemsSource,RelativeSource={RelativeSource TemplatedParent}}" SelectedValue="{TemplateBinding SelectedValue}" ItemTemplate="{TemplateBinding ItemTemplate}" 
                                     ItemsPanel="{TemplateBinding ItemsPanel}" MaxHeight="{TemplateBinding MaxDropDownHeight}"
                                     ItemContainerStyle="{StaticResource ListBoxCheckBoxItemStayle}"/>
                    </Border>
                </Themes:SystemDropShadowChrome>
            </Popup>
            <ToggleButton x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxToggleButton}"/>
            <Border x:Name="border" Background="{StaticResource TextBox.Static.Background}" Margin="{TemplateBinding BorderThickness}">
                <TextBox x:Name="PART_EditableTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Margin="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </Border>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Opacity" TargetName="border" Value="0.56"/>
            </Trigger>
            <Trigger Property="IsKeyboardFocusWithin" Value="true">
                <Setter Property="Foreground" Value="Black"/>
            </Trigger>
            <Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
                <Setter Property="Margin" TargetName="shadow" Value="0,0,5,5"/>
                <Setter Property="Color" TargetName="shadow" Value="#71000000"/>
            </Trigger>
            <Trigger Property="HasItems" Value="false">
                <Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
            </Trigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsGrouping" Value="true"/>
                    <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
                </MultiTrigger.Conditions>
                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
            </MultiTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    <!-- 样式属性 -->
    <Style TargetType="{x:Type local:MultiComboBox}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
        <Setter Property="Background" Value="{StaticResource ComboBox.Static.Background}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ComboBox.Static.Border}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="Padding" Value="6,3,5,3"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
        <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
        <Setter Property="Template" Value="{StaticResource ComboBoxTemplate}"/>
        <Style.Triggers>
            <Trigger Property="IsEditable" Value="true">
                <Setter Property="IsTabStop" Value="false"/>
                <Setter Property="IsTextSearchEnabled" Value="False"/>
                <Setter Property="Padding" Value="2"/>
                <Setter Property="Template" Value="{StaticResource ComboBoxEditableTemplate}"/>
            </Trigger>
        </Style.Triggers>
    </Style>
           

2.后台代码

后台获取Template中的ListBox控件,然后更新多选显示信息

/// <summary>
        /// 构造函数
        /// </summary>
        static MultiComboBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiComboBox), new FrameworkPropertyMetadata(typeof(MultiComboBox)));
        }

        /// <summary>
        /// 列表控件
        /// </summary>
        private ListBox _listBox;

        /// <summary>
        /// 重新模板应用函数
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            if (this.IsEditable == true)
            {
                this._listBox = Template.FindName("PART_ListBox", this) as ListBox;
                this._listBox.SelectionChanged += ListBox_SelectionChanged;
            }
        }

        private StringBuilder _sb = new StringBuilder();

        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            _sb.Clear();
            for (int i = 0; i < _listBox.SelectedItems.Count; i++)
            {
                _sb.Append(_listBox.SelectedItems[i].ToString()).Append(';');
            }

            this.Text = _sb.ToString().Trim(';');
        }