wfp MultiComboBox 自己实现

网上找了很多个,都不好, 终于改好了一个, 

<UserControl x:Class="Views.MultiComboBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Letak.Style;component/Styles/Themes/Letak.Dpt.Defaults.xaml" />
            </ResourceDictionary.MergedDictionaries>

            <Thickness x:Key="ControlMargin">0 5 0 0</Thickness>
            <Thickness x:Key="ButtonMargin">10 0 0 0</Thickness>

            <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
                <Grid Height="25">
                    <Border Grid.Column="1" Background="White" Opacity="0"   Cursor="Hand"/>
                    <Path x:Name="Arrow" Grid.Column="1"   Data="M 0 0  6 6 12 0 Z"  VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="None" Fill="#B1B1B1" />
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="true">
                        <Setter TargetName="Arrow" Property="RenderTransform">
                            <Setter.Value>
                                <RotateTransform   CenterX="6" CenterY="3" Angle="180"></RotateTransform>
                            </Setter.Value>
                        </Setter>
                        <Setter TargetName="Arrow" Property="Margin" Value="0 0 0 2"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </ResourceDictionary>
    </UserControl.Resources>

    <ComboBox
        x:Name="MultiCombo"  
        SnapsToDevicePixels="True"
        OverridesDefaultStyle="True"
        ScrollViewer.HorizontalScrollBarVisibility="Auto"
        ScrollViewer.VerticalScrollBarVisibility="Auto"
        ScrollViewer.CanContentScroll="True"
        IsSynchronizedWithCurrentItem="True">
        
        <!--<ComboBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding Title}" IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Click="CheckBox_Click" Tag="{RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}" />
            </DataTemplate>
        </ComboBox.ItemTemplate>-->
        
        <ComboBox.Template>
            <ControlTemplate  TargetType="ComboBox">
                <Grid >
                    <!--<ToggleButton 
                        Name="ToggleButton" Content="{Binding Path=Text,Mode=TwoWay,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
                       Grid.Column="2" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
                        Focusable="false"                        
                        ClickMode="Press" HorizontalContentAlignment="Left" >
                    </ToggleButton>-->
                    <Border x:Name="Bg" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"  Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" 
                                   BorderBrush="{DynamicResource MaterialDesign.Brush.ComboBox.OutlineBorder}" BorderThickness="1"  CornerRadius="4">
                        <Grid x:Name="PART_Root">
                            <Grid x:Name="PART_InnerGrid" Margin="0">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="0.3*" MaxWidth="30" />
                                </Grid.ColumnDefinitions>

                                <ListBox x:Name="PART_ListBoxChk"  SelectionMode="Multiple"   ItemsSource="{Binding SelectedItems,Mode=TwoWay,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
                                     BorderThickness="0" ScrollViewer.VerticalScrollBarVisibility="Disabled">
                                    <ListBox.ItemsPanel>
                                        <ItemsPanelTemplate>
                                            <VirtualizingStackPanel Orientation="Horizontal" VirtualizingStackPanel.IsVirtualizing="True" />
                                        </ItemsPanelTemplate>
                                    </ListBox.ItemsPanel>
                                    <ListBox.ItemContainerStyle>
                                        <Style TargetType="ListBoxItem">
                                            <Setter Property="BorderThickness" Value="0"/>
                                            <Setter Property="Template">
                                                <Setter.Value>
                                                    <ControlTemplate TargetType="ListBoxItem">
                                                        <ContentPresenter  x:Name="bg"></ContentPresenter>
                                                        <!--<ControlTemplate.Triggers>
                                                            <Trigger Property="IsSelected" Value="True">
                                                                <Setter  TargetName="bg"  Property="Visibility" Value="Visible" />
                                                            </Trigger>
                                                            <Trigger Property="IsSelected" Value="False">
                                                                <Setter TargetName="bg" Property="Opacity" Value="0.3" />
                                                                <Setter   Property="Foreground" Value="Gray" />
                                                            </Trigger>
                                                        </ControlTemplate.Triggers>-->
                                                    </ControlTemplate>
                                                </Setter.Value>
                                            </Setter>
                                        </Style>
                                    </ListBox.ItemContainerStyle>
                                    <ListBox.ItemTemplate>
                                        <DataTemplate>
                                            <Border Name="gcbcc">
                                                <CheckBox Name="cbcc" VerticalContentAlignment="Center" Content="{Binding Title}"  IsChecked="{Binding Path=IsSelected, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
                                            </Border>
                                            <!--<DataTemplate.Triggers>
                                                <Trigger SourceName="cbcc" Property="IsChecked" Value="True">
                                                    <Setter TargetName="gcbcc"  Property="Background" Value="Red" />
                                                </Trigger>
                                                <MultiTrigger>
                                                    <MultiTrigger.Conditions>
                                                        <Condition SourceName="gcbcc" Property="IsMouseOver" Value="true" />
                                                        <Condition SourceName="cbcc" Property="IsChecked" Value="false"/>
                                                    </MultiTrigger.Conditions>

                                                    <Setter TargetName="gcbcc" Property="Background" Value="Green" />
                                                    <Setter TargetName="gcbcc" Property="Opacity" Value="0.7"/>

                                                </MultiTrigger>
                                            </DataTemplate.Triggers>-->
                                        </DataTemplate>
                                    </ListBox.ItemTemplate>
                                </ListBox>

                                <!--<TextBlock VerticalAlignment="Center" Text="{Binding Path=Text,Mode=TwoWay,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"></TextBlock>-->

                                <ToggleButton x:Name="PART_DropDownToggle" IsTabStop="False"  
                                          IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
                                          Grid.Column="1" Template="{StaticResource ComboBoxToggleButton}" Margin="-10,0,-10,0" />
                            </Grid>
                        </Grid>
                    </Border>
                    <Popup 
                        Name="Popup"
                        Placement="Bottom"                        
                        AllowsTransparency="True" 
                        Focusable="False"  IsOpen="{TemplateBinding IsDropDownOpen}"
                        PopupAnimation="Slide">
                        <Grid 
                            Name="DropDown"
                            SnapsToDevicePixels="True"  
                            MinWidth="{TemplateBinding ActualWidth}"
                            MaxHeight="{TemplateBinding MaxDropDownHeight}"
                            Background="{DynamicResource MaterialDesign.Brush.ComboBox.Popup.DarkBackground}"
                            >
                        
                            <ListBox x:Name="PART_ListBox" SelectionMode="Multiple"  ItemsSource="{Binding ItemsSource,RelativeSource={RelativeSource TemplatedParent}}"                                                
                                 MaxHeight="{TemplateBinding MaxDropDownHeight}">
                                <ListBox.ItemContainerStyle>
                                    <Style  TargetType="ListBoxItem">
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                                    <!--<Grid  Height="22">
                                                        <Border x:Name="bg" BorderBrush="#eaeaea" BorderThickness="0"/>
                                                        <ContentPresenter Name="content"></ContentPresenter>
                                                        <Border Background="White"  Opacity="0"/>
                                                    </Grid>-->
                                                    <ContentPresenter  x:Name="bg" Height="25"></ContentPresenter>
                                                    <ControlTemplate.Triggers>
                                                        <Trigger Property="IsSelected" Value="True">
                                                            <!--<Setter  TargetName="bg"  Property="Background" Value="Red" />-->
                                                        </Trigger>
                                                        <MultiTrigger>
                                                            <MultiTrigger.Conditions>
                                                                <Condition Property="IsMouseOver" Value="true" />
                                                                <Condition Property="IsSelected" Value="false"/>
                                                            </MultiTrigger.Conditions>

                                                            <!--<Setter TargetName="bg" Property="Background" Value="Green" />-->
                                                            <Setter TargetName="bg" Property="Opacity" Value="0.7"/>
                                                            <Setter   Property="Foreground" Value="White" />

                                                        </MultiTrigger>
                                                        <Trigger Property="IsEnabled" Value="False">
                                                            <Setter TargetName="bg" Property="Opacity" Value="0.3" />
                                                            <Setter   Property="Foreground" Value="Gray" />
                                                        </Trigger>
                                                    </ControlTemplate.Triggers>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </ListBox.ItemContainerStyle>
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <Border Name="gcbcc">
                                            <CheckBox Name="cbcc" VerticalContentAlignment="Center" Content="{Binding Title}" Checked="Checked_Click" Unchecked="Unchecked_Click" IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"/>
                                        </Border>
                                        <DataTemplate.Triggers>
                                            <Trigger SourceName="cbcc" Property="IsChecked" Value="True">
                                                <Setter TargetName="gcbcc"  Property="Background" Value="{DynamicResource MaterialDesign.Brush.DataGrid.ComboBoxSelected}" /> 
                                            </Trigger>
                                            <MultiTrigger>
                                                <MultiTrigger.Conditions>
                                                    <Condition SourceName="gcbcc" Property="IsMouseOver" Value="true" />
                                                    <Condition SourceName="cbcc" Property="IsChecked" Value="false"/>
                                                </MultiTrigger.Conditions>

                                                <Setter TargetName="gcbcc" Property="Background" Value="{DynamicResource MaterialDesign.Brush.ComboBox.HoverBackground}" />
                                                <Setter TargetName="gcbcc" Property="Opacity" Value="0.7"/>

                                            </MultiTrigger>
                                        </DataTemplate.Triggers>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
                        </Grid>
                    </Popup>
                </Grid>
            </ControlTemplate>
        </ComboBox.Template>
    </ComboBox>
</UserControl>

namespace Views
{
    /// <summary>
    /// Interaction logic for MultiComboBox.xaml
    /// </summary>
    public partial class MultiComboBox : UserControl
    {
        private ObservableCollection<MultiComboNode> _nodeList;
        public MultiComboBox()
        {
            InitializeComponent();
            _nodeList = new ObservableCollection<MultiComboNode>();
        }

        #region Dependency Properties

        public static readonly DependencyProperty ItemsSourceProperty =
             DependencyProperty.Register("ItemsSource", typeof(ObservableCollection<MultiComboNode>), typeof(MultiComboBox), new FrameworkPropertyMetadata(null,
        new PropertyChangedCallback(MultiComboBox.OnItemsSourceChanged)));

        public static readonly DependencyProperty SelectedItemsProperty =
         DependencyProperty.Register("SelectedItems", typeof(ObservableCollection<MultiComboNode>), typeof(MultiComboBox), new FrameworkPropertyMetadata(null,
     new PropertyChangedCallback(MultiComboBox.OnSelectedItemsChanged)));

        public static readonly DependencyProperty TextProperty =
           DependencyProperty.Register("Text", typeof(string), typeof(MultiComboBox), new UIPropertyMetadata(string.Empty));

        public static readonly DependencyProperty DefaultTextProperty =
            DependencyProperty.Register("DefaultText", typeof(string), typeof(MultiComboBox), new UIPropertyMetadata(string.Empty));

        public ObservableCollection<MultiComboNode> ItemsSource
        {
            get { return (ObservableCollection<MultiComboNode>)GetValue(ItemsSourceProperty); }
            set
            {
                SetValue(ItemsSourceProperty, value);
            }
        }

        public ObservableCollection<MultiComboNode> SelectedItems
        {
            get { return (ObservableCollection<MultiComboNode>)GetValue(SelectedItemsProperty); }
            set
            {
                SetValue(SelectedItemsProperty, value);
            }
        }

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public string DefaultText
        {
            get { return (string)GetValue(DefaultTextProperty); }
            set { SetValue(DefaultTextProperty, value); }
        }
        #endregion

        #region Events
        private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            MultiComboBox control = (MultiComboBox)d;
            control.DisplayInControl();
        }

        private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            MultiComboBox control = (MultiComboBox)d;
           // control.SelectNodes();
            control.SetText();
            
        }

    
        private void Checked_Click(object sender, RoutedEventArgs e)
        {
            CheckBox clickedBox = (CheckBox)sender;

            SetSelectedItems();

            //SelectedItems.Clear();
            //foreach (Node node in ItemsSource)
            //{
            //    if (node.IsSelected)
            //    {
            //        SelectedItems.Add(node);
            //    }
            //}

            SetText();

        }

        private void Unchecked_Click(object sender, RoutedEventArgs e)
        {
            CheckBox clickedBox = (CheckBox)sender;

            SetSelectedItems();

            //SelectedItems.Remove(clickedBox.Content.ToString());

            //SetSelectedItems();
            SetText();

        }

        #endregion


        #region Methods
    
        private void SetSelectedItems()
        {
            if (SelectedItems == null)
                SelectedItems = new ObservableCollection<MultiComboNode>();
            SelectedItems.Clear();
            foreach (MultiComboNode node in ItemsSource)
            {
                if (node.IsSelected)
                {
                    SelectedItems.Add(node);
                }
            }
        }

        private void DisplayInControl()
        {
            _nodeList.Clear();
            //if (this.ItemsSource.Count > 0)
            //    _nodeList.Add(new Node("All"));
            //foreach (var keyValue in this.ItemsSource)
            //{
            //    Node node = new Node(keyValue.Title);
            //    _nodeList.Add(node);
            //}

            MultiCombo.ItemsSource = this.ItemsSource;
            SetSelectedItems();
            SetText();
        }


        private void SetText()
        {

            //if (this.SelectedItems != null)
            //{
            //    this.Text = string.Empty;
            //    foreach (var item in this.SelectedItems)
            //    {
            //        this.Text += item.Value.ToString() + ",";
            //    }
            //}

            if (this.ItemsSource != null)
            {
                this.Text = string.Empty;
                foreach (var item in this.ItemsSource)
                {
                   if(item.IsSelected)  this.Text += item.Title.ToString() + ",";
                }
            }
        }


        #endregion
    }

    
}

 <local:MultiComboBox Width="200" Height="35" ItemsSource="{Binding SignalSetting.SignalCh1CheckedItems}"   x:Name="MC" />

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值