天天看點

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(';');
        }