zoukankan      html  css  js  c++  java
  • MultiSelectComboBox(一)

    1. MultiSelectComboBox.xaml

    <UserControl x:Class="MultiSelectComboBox.MultiSelectComboBox"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 >
        <ComboBox
            x:Name="MultiSelectCombo" 
            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}"
                              Tag="{RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}"
                              Click="CheckBox_Click"           />
                </DataTemplate>
            </ComboBox.ItemTemplate>
            <ComboBox.Template>
                <ControlTemplate TargetType="ComboBox">
                    <Grid >
                        <ToggleButton
                            x:Name="ToggleButton"
                            Grid.Column="2"
                            IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,
                            RelativeSource={RelativeSource TemplatedParent}}"
                            Focusable="false"                          
                            ClickMode="Press" HorizontalContentAlignment="Left" >
                            <ToggleButton.Template>
                                <ControlTemplate>
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="18"/>
                                        </Grid.ColumnDefinitions>
                                        <Border
                      x:Name="Border"
                      Grid.ColumnSpan="2"
                      CornerRadius="2"
                      Background="White"
                      BorderBrush="Black"
                      BorderThickness="1,1,1,1" />
                                        <Border
                        x:Name="BorderComp"
                      Grid.Column="0"
                      CornerRadius="2"
                      Margin="1"
                     Background="White"
                      BorderBrush="Black"
                      BorderThickness="0,0,0,0" >
                                            <TextBlock Text="{Binding Path=Text,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
                                                   Background="White" Padding="3" />
                                        </Border>
                                        <Path
                      x:Name="Arrow"
                      Grid.Column="1"    
                      Fill="Black"
                      HorizontalAlignment="Center"
                      VerticalAlignment="Center"
                      Data="M 0 0 L 4 4 L 8 0 Z"/>
                                    </Grid>
                                </ControlTemplate>
                            </ToggleButton.Template>
                             </ToggleButton>
                            <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}">
                                <Border
                                        x:Name="DropDownBorder"
                                       BorderThickness="1" Background="White"
                                        BorderBrush="Black"/>
                                <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True" DataContext="{Binding}">
                                    <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                                </ScrollViewer>
                            </Grid>
                        </Popup>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasItems" Value="false">
                            <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
                        </Trigger>
                        <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
                            <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="4"/>
                            <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </ComboBox.Template>
        </ComboBox>
    </UserControl>

    2. MultiSelectComboBox.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Collections.ObjectModel;
    using System.ComponentModel;

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

            #region Dependency Properties

            public static readonly DependencyProperty ItemsSourceProperty =
                 DependencyProperty.Register("ItemsSource", typeof(Dictionary<string, object>), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null,
            new PropertyChangedCallback(MultiSelectComboBox.OnItemsSourceChanged)));

            public static readonly DependencyProperty SelectedItemsProperty =
             DependencyProperty.Register("SelectedItems", typeof(Dictionary<string, object>), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null,
         new PropertyChangedCallback(MultiSelectComboBox.OnSelectedItemsChanged)));

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

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

            public Dictionary<string, object> ItemsSource
            {
                get { return (Dictionary<string, object>)GetValue(ItemsSourceProperty); }
                set
                {
                    SetValue(ItemsSourceProperty, value);
                }
            }

            public Dictionary<string, object> SelectedItems
            {
                get { return (Dictionary<string, object>)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)
            {
                MultiSelectComboBox control = (MultiSelectComboBox)d;
                control.DisplayInControl();
            }

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

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

                if (clickedBox.Content == "All" )
                {
                    if (clickedBox.IsChecked.Value)
                    {
                        foreach (Node node in _nodeList)
                        {
                            node.IsSelected = true;
                        }
                    }
                    else
                    {
                        foreach (Node node in _nodeList)
                        {
                            node.IsSelected = false;
                        }
                    }

                }
                else
                {
                    int _selectedCount = 0;
                    foreach (Node s in _nodeList)
                    {
                        if (s.IsSelected && s.Title != "All")
                            _selectedCount++;
                    }
                    if (_selectedCount == _nodeList.Count - 1)
                        _nodeList.FirstOrDefault(i => i.Title == "All").IsSelected = true;
                    else
                        _nodeList.FirstOrDefault(i => i.Title == "All").IsSelected = false;
                }
                SetSelectedItems();
                SetText();

            }
            #endregion

            #region Methods
            private void SelectNodes()
            {
                foreach (KeyValuePair<string, object> keyValue in SelectedItems)
                {
                    Node node = _nodeList.FirstOrDefault(i => i.Title == keyValue.Key);
                    if (node != null)
                        node.IsSelected = true;
                }
            }

            private void SetSelectedItems()
            {
                if (SelectedItems == null)
                    SelectedItems = new Dictionary<string, object>();
                SelectedItems.Clear();
                foreach (Node node in _nodeList)
                {
                    if (node.IsSelected && node.Title != "All")
                    {
                        if (this.ItemsSource.Count > 0)

                            SelectedItems.Add(node.Title, this.ItemsSource[node.Title]);
                    }
                }
            }

            private void DisplayInControl()
            {
                _nodeList.Clear();
                if (this.ItemsSource.Count > 0)
                    _nodeList.Add(new Node("All"));
                foreach (KeyValuePair<string, object> keyValue in this.ItemsSource)
                {
                    Node node = new Node(keyValue.Key);
                    _nodeList.Add(node);
                }
                MultiSelectCombo.ItemsSource = _nodeList;
            }

            private void SetText()
            {
                if (this.SelectedItems != null)
                {
                    StringBuilder displayText = new StringBuilder();
                    foreach (Node s in _nodeList)
                    {
                        if (s.IsSelected == true && s.Title == "All")
                        {
                            displayText = new StringBuilder();
                            displayText.Append("All");
                            break;
                        }
                        else if (s.IsSelected == true && s.Title != "All")
                        {
                            displayText.Append(s.Title);
                            displayText.Append(',');
                        }
                    }
                    this.Text = displayText.ToString().TrimEnd(new char[] { ',' });
                }          
                // set DefaultText if nothing else selected
                if (string.IsNullOrEmpty(this.Text))
                {
                    this.Text = this.DefaultText;
                }
            }

            #endregion
        }

        public class Node : INotifyPropertyChanged
        {

            private string _title;
            private bool _isSelected;
            #region ctor
            public Node(string title)
            {
                Title = title;
            }
            #endregion

            #region Properties
            public string Title
            {
                get
                {
                    return _title;
                }
                set
                {
                    _title = value;
                    NotifyPropertyChanged("Title");
                }
            }
            public bool IsSelected
            {
                get
                {
                    return _isSelected;
                }
                set
                {
                    _isSelected = value;
                    NotifyPropertyChanged("IsSelected");
                }
            }
            #endregion

            public event PropertyChangedEventHandler PropertyChanged;
            protected void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }

        }
    }

  • 相关阅读:
    Python学习笔记(十一)
    Python学习笔记(十)
    Python学习笔记(九)
    Fatal error in launcher:Unable to create process using '"'
    通过xrdp服务实现windows远程桌面连接树莓派
    Python学习笔记(七)
    Python 杂集
    Python入门小练习
    Python标准库
    [Chrome](CSS) 解决Chrome font-size 小于 12px 无效
  • 原文地址:https://www.cnblogs.com/zisezhixin/p/4106897.html
Copyright © 2011-2022 走看看