日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

基于WPF實現多選下拉控件的示例代碼_C#教程

作者:驚鏵 ? 更新時間: 2023-03-29 編程語言

WPF 實現多選下拉控件

框架使用.NET40

Visual Studio 2022;

創建控件?MultiSelectComboBox?繼承?ListBox?。

  • 依賴屬性?IsSelectAllActive?是否支持顯示全選,默認?false?。
  • 依賴屬性?SelectAllContent?全選控件的?Content,默認顯示?全選?。
  • 依賴屬性?Delimiter?分隔符,默認顯示?;?。
  • 依賴屬性?Text?顯示選擇的所有?Item?。
  • 其他與ComboBox?依賴屬性一致。

實現代碼

1)?MultiSelectComboBox.xaml?代碼如下:

using?System;
using?System.ComponentModel;
using?System.Linq;
using?System.Windows;
using?System.Windows.Controls;
using?System.Windows.Controls.Primitives;
using?System.Windows.Input;
using?System.Windows.Threading;

namespace?WPFDevelopers.Controls
{
????public?class?MultiSelectComboBox?:?ListBox
????{
????????private?const?string?PART_Popup?=?"PART_Popup";
????????private?const?string?PART_CheckBoxAll?=?"PART_CheckBoxAll";

????????public?static?readonly?DependencyProperty?IsDropDownOpenProperty?=
????????????DependencyProperty.Register("IsDropDownOpen",?typeof(bool),?typeof(MultiSelectComboBox),
????????????????new?PropertyMetadata(false));

????????public?static?readonly?DependencyProperty?MaxDropDownHeightProperty
????????????=?DependencyProperty.Register("MaxDropDownHeight",?typeof(double),?typeof(MultiSelectComboBox),
????????????????new?PropertyMetadata(SystemParameters.PrimaryScreenHeight?/?3));

????????public?static?readonly?DependencyProperty?SelectAllContentProperty?=
????????????DependencyProperty.Register("SelectAllContent",?typeof(object),?typeof(MultiSelectComboBox),
????????????????new?PropertyMetadata("全選"));

????????public?static?readonly?DependencyProperty?IsSelectAllActiveProperty?=
????????????DependencyProperty.Register("IsSelectAllActive",?typeof(bool),?typeof(MultiSelectComboBox),
????????????????new?PropertyMetadata(false));

????????public?static?readonly?DependencyProperty?DelimiterProperty?=
????????????DependencyProperty.Register("Delimiter",?typeof(string),?typeof(MultiSelectComboBox),
????????????????new?PropertyMetadata(";"));

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

????????private?bool?_ignoreTextValueChanged;
????????private?MultiSelectComboBoxItem?_multiSelectComboBoxItem;
????????private?Popup?_popup;

????????public?bool?IsDropDownOpen
????????{
????????????get?=>?(bool)GetValue(IsDropDownOpenProperty);
????????????set?=>?SetValue(IsDropDownOpenProperty,?value);
????????}


????????[Bindable(true)]
????????[Category("Layout")]
????????[TypeConverter(typeof(LengthConverter))]
????????public?double?MaxDropDownHeight
????????{
????????????get?=>?(double)GetValue(MaxDropDownHeightProperty);
????????????set?=>?SetValue(MaxDropDownHeightProperty,?value);
????????}


????????public?object?SelectAllContent
????????{
????????????get?=>?GetValue(SelectAllContentProperty);
????????????set?=>?SetValue(SelectAllContentProperty,?value);
????????}


????????public?bool?IsSelectAllActive
????????{
????????????get?=>?(bool)GetValue(IsSelectAllActiveProperty);
????????????set?=>?SetValue(IsSelectAllActiveProperty,?value);
????????}


????????public?string?Delimiter
????????{
????????????get?=>?(string)GetValue(DelimiterProperty);
????????????set?=>?SetValue(DelimiterProperty,?value);
????????}


????????public?string?Text
????????{
????????????get?=>?(string)GetValue(TextProperty);
????????????set?=>?SetValue(TextProperty,?value);
????????}

????????private?static?void?OnIsDropDownOpenChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????var?MultiSelectComboBox?=?(MultiSelectComboBox)d;

????????????if?(!(bool)e.NewValue)
????????????????MultiSelectComboBox.Dispatcher.BeginInvoke(new?Action(()?=>?{?Mouse.Capture(null);?}),
????????????????????DispatcherPriority.Send);
????????}

????????private?static?void?OnTextChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????}


????????protected?override?bool?IsItemItsOwnContainerOverride(object?item)
????????{
????????????return?item?is?MultiSelectComboBoxItem;
????????}

????????protected?override?DependencyObject?GetContainerForItemOverride()
????????{
????????????return?new?MultiSelectComboBoxItem();
????????}

????????protected?override?void?OnSelectionChanged(SelectionChangedEventArgs?e)
????????{
????????????UpdateText();
????????????base.OnSelectionChanged(e);
????????}

????????public?override?void?OnApplyTemplate()
????????{
????????????base.OnApplyTemplate();

????????????_popup?=?GetTemplateChild(PART_Popup)?as?Popup;
????????????_multiSelectComboBoxItem?=?GetTemplateChild(PART_CheckBoxAll)?as?MultiSelectComboBoxItem;
????????????_multiSelectComboBoxItem.Selected?+=?_MultiSelectComboBoxItem_Selected;
????????????_multiSelectComboBoxItem.Unselected?+=?_MultiSelectComboBoxItem_Unselected;
????????}

????????private?void?_MultiSelectComboBoxItem_Unselected(object?sender,?RoutedEventArgs?e)
????????{
????????????if?(_ignoreTextValueChanged)?return;
????????????_ignoreTextValueChanged?=?true;
????????????UnselectAll();
????????????_ignoreTextValueChanged?=?false;
????????????UpdateText();
????????}

????????private?void?_MultiSelectComboBoxItem_Selected(object?sender,?RoutedEventArgs?e)
????????{
????????????if?(_ignoreTextValueChanged)?return;
????????????_ignoreTextValueChanged?=?true;
????????????SelectAll();
????????????_ignoreTextValueChanged?=?false;
????????????UpdateText();
????????}

????????protected?virtual?void?UpdateText()
????????{
????????????if?(_ignoreTextValueChanged)?return;
????????????var?newValue?=?string.Join(Delimiter,?SelectedItems.Cast<object>().Select(x?=>?GetItemDisplayValue(x)));
????????????if?(string.IsNullOrWhiteSpace(Text)?||?!Text.Equals(newValue))
????????????{
????????????????_ignoreTextValueChanged?=?true;
????????????????if?(_multiSelectComboBoxItem?!=?null)
????????????????????_multiSelectComboBoxItem.SetCurrentValue(IsSelectedProperty,?SelectedItems.Count?==?Items.Count);
????????????????SetCurrentValue(TextProperty,?newValue);
????????????????_ignoreTextValueChanged?=?false;
????????????}
????????????
????????}

????????protected?object?GetItemDisplayValue(object?item)
????????{
????????????if?(string.IsNullOrWhiteSpace(DisplayMemberPath))
????????????{
????????????????var?property?=?item.GetType().GetProperty("Content");
????????????????if?(property?!=?null)
????????????????????return?property.GetValue(item,?null);
????????????}

????????????var?nameParts?=?DisplayMemberPath.Split('.');
????????????if?(nameParts.Length?==?1)
????????????{
????????????????var?property?=?item.GetType().GetProperty(DisplayMemberPath);
????????????????if?(property?!=?null)
????????????????????return?property.GetValue(item,?null);
????????????}

????????????return?item;
????????}
????}
}

2)?MultiSelectComboBoxItem.cs?代碼如下:

using?System.Windows.Controls;

namespace?WPFDevelopers.Controls
{
????public?class?MultiSelectComboBoxItem?:?ListBoxItem
????{
????}
}

3)?MultiSelectComboBox.xaml?代碼如下:

<ResourceDictionary?xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????????????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????????????????????xmlns:controls="clr-namespace:WPFDevelopers.Controls"
????????????????????xmlns:helpers="clr-namespace:WPFDevelopers.Helpers">
????
????<ResourceDictionary.MergedDictionaries>
????????<ResourceDictionary?Source="Basic/ControlBasic.xaml"/>
????</ResourceDictionary.MergedDictionaries>
??<BooleanToVisibilityConverter?x:Key="bool2VisibilityConverter"?/>
?<Style?x:Key="DefaultMultiSelectComboBoxItem"?TargetType="{x:Type?controls:MultiSelectComboBoxItem}">
??<Setter?Property="HorizontalContentAlignment"?Value="{Binding?HorizontalContentAlignment,?RelativeSource={RelativeSource?AncestorType={x:Type?ItemsControl}}}"/>
??<Setter?Property="VerticalContentAlignment"?Value="{Binding?VerticalContentAlignment,?RelativeSource={RelativeSource?AncestorType={x:Type?ItemsControl}}}"/>
??<Setter?Property="SnapsToDevicePixels"?Value="True"/>
??<Setter?Property="Background"?Value="Transparent"/>
??<Setter?Property="BorderBrush"?Value="Transparent"/>
??<Setter?Property="Foreground"?Value="{DynamicResource?RegularTextSolidColorBrush}"/>
??<Setter?Property="BorderThickness"?Value="0"/>
??<Setter?Property="Height"?Value="34"?/>
??<Setter?Property="Margin"?Value="1,0"?/>
??<Setter?Property="Padding"?Value="6,0"/>
??<Setter?Property="Cursor"?Value="Hand"?/>
??<Setter?Property="Template">
???<Setter.Value>
????<ControlTemplate?TargetType="{x:Type?controls:MultiSelectComboBoxItem}">

?????<Border?x:Name="PART_Border"
???????BorderBrush="{TemplateBinding?BorderBrush}"
???????BorderThickness="{TemplateBinding?BorderThickness}"
???????Background="{TemplateBinding?Background}"
???????SnapsToDevicePixels="true"
???????Padding="{TemplateBinding?Padding}">
??????<CheckBox?Foreground="{TemplateBinding?Foreground}"
??????????HorizontalAlignment="Stretch"
??????????VerticalAlignment="{TemplateBinding?VerticalContentAlignment}"
??????????MinHeight="{TemplateBinding?MinHeight}"
??????????Padding="{TemplateBinding?Padding}"
??????????IsChecked="{Binding?IsSelected,RelativeSource={RelativeSource?TemplatedParent},Mode=TwoWay}">

???????<ContentPresenter?HorizontalAlignment="{TemplateBinding?HorizontalContentAlignment}"
??????????VerticalAlignment="{TemplateBinding?VerticalContentAlignment}"
??????????x:Name="PART_ContentPresenter"
??????????SnapsToDevicePixels="{TemplateBinding?SnapsToDevicePixels}"
??????????TextElement.Foreground="{TemplateBinding?Foreground}"/>
??????</CheckBox>
?????</Border>
?????<ControlTemplate.Triggers>
??????<Trigger?Property="IsMouseOver"?Value="True">
???????<Setter?Property="Background"?Value="{DynamicResource?DefaultBackgroundSolidColorBrush}"/>
??????</Trigger>
?????</ControlTemplate.Triggers>
????</ControlTemplate>
???</Setter.Value>
??</Setter>
?</Style>

?<Style?TargetType="{x:Type?controls:MultiSelectComboBox}">
??<Setter?Property="ScrollViewer.HorizontalScrollBarVisibility"?Value="Auto"?/>
??<Setter?Property="ScrollViewer.VerticalScrollBarVisibility"?Value="Auto"?/>
??<Setter?Property="ScrollViewer.CanContentScroll"?Value="True"?/>
??<Setter?Property="SelectionMode"?Value="Multiple"/>
??<Setter?Property="MinWidth"?Value="120"?/>
??<Setter?Property="MinHeight"?Value="{StaticResource?MinHeight}"?/>
????????<Setter?Property="Height"?Value="{StaticResource?MinHeight}"?/>
??<Setter?Property="ItemContainerStyle"?Value="{StaticResource?DefaultMultiSelectComboBoxItem}"/>
??<Setter?Property="HorizontalContentAlignment"?Value="Left"?/>
??<Setter?Property="VerticalContentAlignment"?Value="Center"?/>
????????<Setter?Property="BorderBrush"?Value="{DynamicResource?BaseSolidColorBrush}"/>
????????<Setter?Property="BorderThickness"?Value="1"/>
??<Setter?Property="Background"?Value="{DynamicResource?BackgroundSolidColorBrush}"/>
??<Setter?Property="Padding"?Value="14.5,3,30,3"/>
??<Setter?Property="Template">
???<Setter.Value>
????????????????<ControlTemplate?TargetType="{x:Type?controls:MultiSelectComboBox}">
?????<ControlTemplate.Resources>
??????<Storyboard?x:Key="OpenStoryboard">
???????<DoubleAnimation?Storyboard.TargetName="PART_DropDown"
?????????????Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)"
?????????????To="1"?Duration="00:00:.2"
?????????????EasingFunction="{StaticResource?ExponentialEaseOut}"/>
??????</Storyboard>
??????<Storyboard?x:Key="CloseStoryboard">
???????<DoubleAnimation?Storyboard.TargetName="PART_DropDown"
?????????????Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)"
?????????????To="0"?Duration="00:00:.2"
?????????????EasingFunction="{StaticResource?ExponentialEaseOut}"/>
??????</Storyboard>
?????</ControlTemplate.Resources>
????????????????????<controls:SmallPanel?SnapsToDevicePixels="True">
??????<Border?Name="PART_Border"
????????Background="{TemplateBinding?Background}"
????????BorderBrush="{TemplateBinding?BorderBrush}"
????????BorderThickness="{TemplateBinding?BorderThickness}"
????????SnapsToDevicePixels="True"
????????CornerRadius="{Binding?Path=(helpers:ElementHelper.CornerRadius),?RelativeSource={RelativeSource?TemplatedParent}}"?/>


??????<ToggleButton?x:Name="PART_ToggleButton"
???????????Template="{StaticResource?ComboBoxToggleButton}"
???????????Style="{x:Null}"
???????????Focusable="False"
???????????ClickMode="Release"
???????????IsChecked="{Binding?IsDropDownOpen,?Mode=TwoWay,?RelativeSource={RelativeSource?TemplatedParent}}"/>
??????<TextBox?Name="PART_EditableTextBox"
?????????Template="{StaticResource?ComboBoxTextBox}"
?????????HorizontalAlignment="{TemplateBinding?HorizontalContentAlignment}"
?????????VerticalAlignment="{TemplateBinding?VerticalContentAlignment}"
?????????Margin="{TemplateBinding?Padding}"
?????????Focusable="True"
?????????Text="{Binding?Text,RelativeSource={RelativeSource?TemplatedParent},Mode=TwoWay}"
?????????Background="{TemplateBinding?Background}"
?????????SelectionBrush="{DynamicResource?WindowBorderBrushSolidColorBrush}"
?????????IsReadOnly="True"?Style="{x:Null}"?/>
??????
??????<Popup?x:Name="PART_Popup"
????????AllowsTransparency="True"
????????PlacementTarget="{Binding?ElementName=PART_ToggleButton}"
????????IsOpen="{Binding?IsDropDownOpen,RelativeSource={RelativeSource?TemplatedParent},Mode=TwoWay}"
????????Placement="Bottom"?StaysOpen="False">
????????????????????????????<controls:SmallPanel?x:Name="PART_DropDown"
??????????MinWidth="{TemplateBinding?FrameworkElement.ActualWidth}"
????????Margin="24,2,24,24"
????????MaxHeight="{TemplateBinding?MaxDropDownHeight}"
????????RenderTransformOrigin=".5,0"
????????SnapsToDevicePixels="True">
????????????????????????????????<controls:SmallPanel.RenderTransform>
?????????<ScaleTransform?ScaleY="0"/>
????????</controls:SmallPanel.RenderTransform>
????????<Border
?????????Name="PART_DropDownBorder"
?????????Background="{TemplateBinding?Background}"
?????????BorderBrush="{TemplateBinding?BorderBrush}"
?????????BorderThickness="{TemplateBinding?BorderThickness}"
?????????SnapsToDevicePixels="True"
?????????????????????????????????CornerRadius="{Binding?Path=(helpers:ElementHelper.CornerRadius),RelativeSource={RelativeSource?TemplatedParent}}"
?????????UseLayoutRounding="True"
?????????Effect="{StaticResource?PopupShadowDepth}"/>
????????<Grid?ClipToBounds="False"
???????????Margin="0,8"?>
?????????<Grid.RowDefinitions>
??????????<RowDefinition?Height="Auto"/>
??????????<RowDefinition/>
?????????</Grid.RowDefinitions>
?????????<controls:MultiSelectComboBoxItem?x:Name="PART_CheckBoxAll"
????????????????????Visibility="{TemplateBinding?IsSelectAllActive,Converter={StaticResource?bool2VisibilityConverter}}"
????????????????????Style="{TemplateBinding?ItemContainerStyle}"
????????????????????Content="{TemplateBinding?SelectAllContent}"/>
?????????<ScrollViewer?x:Name="DropDownScrollViewer"?Grid.Row="1"
???????????????ScrollViewer.VerticalScrollBarVisibility="Auto">
??????????<ItemsPresenter?x:Name="ItemsPresenter"
???????????????KeyboardNavigation.DirectionalNavigation="Contained"
???????????????SnapsToDevicePixels="{TemplateBinding?SnapsToDevicePixels}"/>
?????????</ScrollViewer>
????????</Grid>
???????</controls:SmallPanel>
??????</Popup>
?????</controls:SmallPanel>
?????<ControlTemplate.Triggers>
??????<Trigger?SourceName="PART_ToggleButton"?Property="IsChecked"?Value="True">
???????<Trigger.EnterActions>
????????<BeginStoryboard?x:Name="BeginStoryboardOpenStoryboard"?Storyboard="{StaticResource?OpenStoryboard}"?/>
???????</Trigger.EnterActions>
???????<Trigger.ExitActions>
????????<StopStoryboard?BeginStoryboardName="BeginStoryboardOpenStoryboard"?/>
???????</Trigger.ExitActions>
??????</Trigger>
??????<Trigger?SourceName="PART_ToggleButton"?Property="IsChecked"?Value="False">
???????<Trigger.EnterActions>
????????<BeginStoryboard?x:Name="BeginStoryboardCloseStoryboard"?Storyboard="{StaticResource?CloseStoryboard}"?/>
???????</Trigger.EnterActions>
???????<Trigger.ExitActions>
????????<StopStoryboard?BeginStoryboardName="BeginStoryboardCloseStoryboard"?/>
???????</Trigger.ExitActions>
??????</Trigger>
??????<Trigger?Property="IsMouseOver"?Value="True">
????????????????????????????<Setter?Property="BorderBrush"?TargetName="PART_Border"?Value="{DynamicResource?PrimaryNormalSolidColorBrush}"/>
??????</Trigger>
??????<Trigger?SourceName="PART_Popup"?Property="AllowsTransparency"?Value="True">
???????<Setter?TargetName="PART_DropDownBorder"??Property="Margin"?Value="0,2,0,0"?/>
??????</Trigger>
?????</ControlTemplate.Triggers>
????</ControlTemplate>
???</Setter.Value>
??</Setter>
?</Style>
</ResourceDictionary>

4)?MultiSelectComboBoxExample.xaml?代碼如下:

<UserControl?x:Class="WPFDevelopers.Samples.ExampleViews.MultiSelectComboBoxExample"
?????????????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
?????????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
?????????????xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"?
?????????????xmlns:d="http://schemas.microsoft.com/expression/blend/2008"?
?????????????xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
?????????????xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
?????????????xmlns:controls="clr-namespace:WPFDevelopers.Samples.Controls"
?????????????xmlns:model="clr-namespace:WPFDevelopers.Sample.Models"
?????????????mc:Ignorable="d"?
?????????????d:DesignHeight="450"?d:DesignWidth="800">
????<UserControl.Resources>
????????<model:HospitalList?x:Key="myHospitalList"/>
????</UserControl.Resources>
????<controls:CodeViewer>
????????<UniformGrid?Columns="2">
????????????<wpfdev:MultiSelectComboBox
????????????????VerticalContentAlignment="Center"?
????????????????HorizontalAlignment="Center"
????????????????Delimiter="^"?Width="200">
????????????????<wpfdev:MultiSelectComboBoxItem>Option?1</wpfdev:MultiSelectComboBoxItem>
????????????????<wpfdev:MultiSelectComboBoxItem>Option?2</wpfdev:MultiSelectComboBoxItem>
????????????????<wpfdev:MultiSelectComboBoxItem>Option?3</wpfdev:MultiSelectComboBoxItem>
????????????????<wpfdev:MultiSelectComboBoxItem>Option?4</wpfdev:MultiSelectComboBoxItem>
????????????????<wpfdev:MultiSelectComboBoxItem>Option?5</wpfdev:MultiSelectComboBoxItem>
????????????</wpfdev:MultiSelectComboBox>
????????????<wpfdev:MultiSelectComboBox?VerticalContentAlignment="Center"?
?????????????????????????????????????????HorizontalAlignment="Center"
?????????????????????????????????????????IsSelectAllActive="True"
?????????????????????????????ItemsSource="{Binding?Source={StaticResource?myHospitalList}}"
?????????????????????????????DisplayMemberPath="DoctorName"
?????????????????????????????SelectedValuePath="ID"?Width="200">

????????????</wpfdev:MultiSelectComboBox>
????????</UniformGrid>
????????<controls:CodeViewer.SourceCodes>
????????????<controls:SourceCodeModel?
????????????????CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/MultiSelectComboBoxExample.xaml"?
????????????????CodeType="Xaml"/>
????????????<controls:SourceCodeModel?
????????????????CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/MultiSelectComboBoxExample.xaml.cs"?
????????????????CodeType="CSharp"/>
????????</controls:CodeViewer.SourceCodes>
????</controls:CodeViewer>
</UserControl>

效果圖

原文鏈接:https://mp.weixin.qq.com/s/uHloylkBzIbuxEiC5KEyBA

欄目分類
最近更新