赞
踩
不想自己撸代码的可以使用免费的XiaFControl控件库,在nuget包中搜索XiaFControl。各种控件都有哦!
示例代码:
github示例demo代码https://github.com/LiuliuMao/XiaFControl
gitee示例demo代码https://gitee.com/lm961031/xia-fcontrol
QQ交流群:371769310
/// <summary> /// MultiSelectComboBox.xaml 的交互逻辑 /// </summary> public partial class MultiSelectComboBox : UserControl { private ObservableCollection<Node> _nodeList; 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 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(); } 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 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 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; } } public MultiSelectComboBox() { InitializeComponent(); _nodeList = new ObservableCollection<Node>(); } public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register ("SelectedItems", typeof(Dictionary<string, object>), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null, new PropertyChangedCallback (MultiSelectComboBox.OnSelectedItemsChanged))); private static void OnSelectedItemsChanged (DependencyObject d, DependencyPropertyChangedEventArgs e) { MultiSelectComboBox control = (MultiSelectComboBox)d; control.SelectNodes(); control.SetText(); } public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(Dictionary<string, object>), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(MultiSelectComboBox.OnItemsSourceChanged))); private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { MultiSelectComboBox control = (MultiSelectComboBox)d; control.DisplayInControl(); } //public static readonly DependencyProperty ItemsSourceProperty = // DependencyProperty.Register("ItemsSource", typeof(Dictionary<string, object>), // typeof(MultiSelectComboBox), new UIPropertyMetadata(string.Empty)); 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); } } } 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)); } } }
Text属性是用来显示多选项的值,在没有选中项的时候Text的值等于DefaultText属性的值,可以在使用时,将DefaultText赋值请选择之类的提示语。
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 IsOpen="{TemplateBinding IsDropDownOpen}" PopupAnimation="Slide" Name="Popup" Placement="Bottom" AllowsTransparency="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}" Focusable="False" > <Grid Name="DropDown" SnapsToDevicePixels="True" > <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>
使用时调用:
<Grid>
<wpfcon:MultiSelectComboBox SelectedItems="{Binding SelectedItems}" ItemsSource="{Binding Items}"/>
</Grid>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。