<ComboBox x:Class="View.AutoCompleteComboBox"
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:View"
mc:Ignorable="d"
d:DesignWidth="300"
d:DesignHeight="300"
IsEditable="True"
IsTextSearchEnabled="False"
PreviewKeyDown="ComboBox_PreviewKeyDown"
/>
AutoCompleteComboBox.xaml.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
namespace View
{
/// <summary>
/// AutoCompleteComboBox.xaml
/// </summary>
public partial class AutoCompleteComboBox : ComboBox
{
readonly SerialDisposable disposable = new SerialDisposable();
TextBox editableTextBoxCache;
Predicate<object> defaultItemsFilter;
public TextBox EditableTextBox
{
get
{
if (editableTextBoxCache == null)
{
const string name = "PART_EditableTextBox";
editableTextBoxCache = (TextBox)VisualTreeModule.FindChild(this, name);
}
return editableTextBoxCache;
}
}
/// <summary>
/// Gets text to match with the query from an item.
/// Never null.
/// </summary>
/// <param name="item"/>
string TextFromItem(object item)
{
if (item == null) return string.Empty;
var d = new DependencyVariable<string>();
d.SetBinding(item, TextSearch.GetTextPath(this));
return d.Value ?? string.Empty;
}
protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
base.OnItemsSourceChanged(oldValue, newValue);
defaultItemsFilter = newValue is ICollectionView cv ? cv.Filter : null;
}
#region Setting
static readonly DependencyProperty settingProperty =
DependencyProperty.Register(
"Setting",
typeof(AutoCompleteComboBoxSetting),
typeof(AutoCompleteComboBox)
);
public static DependencyProperty SettingProperty
{
get { return settingProperty; }
}
public AutoCompleteComboBoxSetting Setting
{
get { return (AutoCompleteComboBoxSetting)GetValue(SettingProperty); }
set { SetValue(SettingProperty, value); }
}
AutoCompleteComboBoxSetting SettingOrDefault
{
get { return Setting ?? AutoCompleteComboBoxSetting.Default; }
}
#endregion
#region OnTextChanged
long revisionId;
string previousText;
struct TextBoxStatePreserver
: IDisposable
{
readonly TextBox textBox;
readonly int selectionStart;
readonly int selectionLength;
readonly string text;
public void Dispose()
{
textBox.Text = text;
textBox.Select(selectionStart, selectionLength);
}
public TextBoxStatePreserver(TextBox textBox)
{
this.textBox = textBox;
selectionStart = textBox.SelectionStart;
selectionLength = textBox.SelectionLength;
text = textBox.Text;
}
}
static int CountWithMax<T>(IEnumerable<T> xs, Predicate<T> predicate, int maxCount)
{
var count = 0;
foreach (var x in xs)
{
if (predicate(x))
{
count++;
if (count > maxCount) return count;
}
}
return count;
}
void Unselect()
{
var textBox = EditableTextBox;
textBox.Select(textBox.SelectionStart + textBox.SelectionLength, 0);
}
void UpdateFilter(Predicate<object> filter)
{
using (new TextBoxStatePreserver(EditableTextBox))
using (Items.DeferRefresh())
{
// Can empty the text box. I don't why.
Items.Filter = filter;
}
}
void OpenDropDown(Predicate<object> filter)
{
UpdateFilter(filter);
IsDropDownOpen = true;
Unselect();
}
void OpenDropDown()
{
var filter = GetFilter();
OpenDropDown(filter);
}
void UpdateSuggestionList()
{
var text = Text;
if (text == previousText) return;
previousText = text;
if (string.IsNullOrEmpty(text))
{
IsDropDownOpen = false;
SelectedItem = null;
using (Items.DeferRefresh())
{
Items.Filter = defaultItemsFilter;
}
}
else if (SelectedItem != null && TextFromItem(SelectedItem) == text)
{
// It seems the user selected an item.
// Do nothing.
}
else
{
using (new TextBoxStatePreserver(EditableTextBox))
{
SelectedItem = null;
}
var filter = GetFilter();
var maxCount = SettingOrDefault.MaxSuggestionCount;
var count = CountWithMax(ItemsSource?.Cast<object>() ?? Enumerable.Empty<object>(), filter, maxCount);
if (count > maxCount) return;
OpenDropDown(filter);
}
}
void OnTextChanged(object sender, TextChangedEventArgs e)
{
var id = unchecked(++revisionId);
var setting = SettingOrDefault;
if (setting.Delay <= TimeSpan.Zero)
{
UpdateSuggestionList();
return;
}
disposable.Content =
new Timer(
state =>
{
Dispatcher.InvokeAsync(() =>
{
if (revisionId != id) return;
UpdateSuggestionList();
});
},
null,
setting.Delay,
Timeout.InfiniteTimeSpan
);
}
#endregion
void ComboBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers.HasFlag(ModifierKeys.Control) && e.Key == Key.Space)
{
OpenDropDown();
e.Handled = true;
}
}
Predicate<object> GetFilter()
{
var filter = SettingOrDefault.GetFilter(Text, TextFromItem);
return defaultItemsFilter != null
? i => defaultItemsFilter(i) && filter(i)
: filter;
}
public AutoCompleteComboBox()
{
InitializeComponent();
AddHandler(TextBoxBase.TextChangedEvent, new TextChangedEventHandler(OnTextChanged));
}
}
}
AutoCompleteComboBoxSetting.cs
using System;
namespace View
{
/// <summary>
/// Represents an object to configure <see cref="AutoCompleteComboBox"/>.
/// </summary>
public class AutoCompleteComboBoxSetting
{
/// <summary>
/// Gets a filter function which determines whether items should be suggested or not
/// for the specified query.
/// Default: Gets the filter which maps an item to <c>true</c>
/// if its text contains the query (case insensitive).
/// </summary>
/// <param name="query">
/// The string input by user.
/// </param>
/// <param name="stringFromItem">
/// The function to get a string which identifies the specified item.
/// </param>
/// <returns></returns>
public virtual Predicate<object> GetFilter(string query, Func<object, string> stringFromItem)
{
return item => stringFromItem(item).IndexOf(query, StringComparison.InvariantCultureIgnoreCase) >= 0;
}
/// <summary>
/// Gets an integer.
/// The combobox opens the drop down
/// if the number of suggested items is less than the value.
/// Note that the value is larger, it's heavier to open the drop down.
/// Default: 100.
/// </summary>
public virtual int MaxSuggestionCount
{
get { return 100; }
}
/// <summary>
/// Gets the duration to delay updating the suggestion list.
/// Returns <c>Zero</c> if no delay.
/// Default: 300ms.
/// </summary>
public virtual TimeSpan Delay
{
get { return TimeSpan.FromMilliseconds(300.0); }
}
static AutoCompleteComboBoxSetting @default = new AutoCompleteComboBoxSetting();
/// <summary>
/// Gets the default setting.
/// </summary>
public static AutoCompleteComboBoxSetting Default
{
get { return @default; }
set
{
if (value == null) throw new ArgumentNullException(nameof(value));
@default = value;
}
}
}
}
DependencyVariable.cs
using System;
using System.Windows;
using System.Windows.Data;
namespace View
{
sealed class DependencyVariable<T>
: DependencyObject
{
static readonly DependencyProperty valueProperty =
DependencyProperty.Register(
"Value",
typeof(T),
typeof(DependencyVariable<T>)
);
public static DependencyProperty ValueProperty
{
get { return valueProperty; }
}
public T Value
{
get { return (T)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public void SetBinding(Binding binding)
{
BindingOperations.SetBinding(this, ValueProperty, binding);
}
public void SetBinding(object dataContext, string propertyPath)
{
SetBinding(new Binding(propertyPath) { Source = dataContext });
}
}
}
SerialDisposable.cs
using System;
namespace View
{
sealed class SerialDisposable
: IDisposable
{
IDisposable content;
public IDisposable Content
{
get { return content; }
set
{
if (content != null)
{
content.Dispose();
}
content = value;
}
}
public void Dispose()
{
Content = null;
}
}
}
VisualTreeModule.cs
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
namespace View
{
static class VisualTreeModule
{
public static FrameworkElement FindChild(DependencyObject obj, string childName)
{
if (obj == null) return null;
var queue = new Queue<DependencyObject>();
queue.Enqueue(obj);
while (queue.Count > 0)
{
obj = queue.Dequeue();
var childCount = VisualTreeHelper.GetChildrenCount(obj);
for (var i = 0; i < childCount; i++)
{
var child = VisualTreeHelper.GetChild(obj, i);
var fe = child as FrameworkElement;
if (fe != null && fe.Name == childName)
{
return fe;
}
queue.Enqueue(child);
}
}
return null;
}
}
}
style
<Style x:Key="ComboBoxToggleButtonDelete" TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Focusable" Value="false" />
<Setter Property="ClickMode" Value="Press" />
<Setter Property="BorderBrush" Value="#BFBFBF" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border CornerRadius="4" BorderBrush="{TemplateBinding BorderBrush}" x:Name="templateRoot" BorderThickness="{TemplateBinding BorderThickness}" Background="White" SnapsToDevicePixels="true">
<Image Source="pack://application:,,,/LabInOne_ESARS;component/Images/PC/delLabel.png" Width="15" Height="15" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,2,5,0" >
</Image>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ComboBox}, Path=Text}" Value="{x:Null}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border CornerRadius="4" BorderBrush="{TemplateBinding BorderBrush}" x:Name="templateRoot" BorderThickness="{TemplateBinding BorderThickness}" Background="White" SnapsToDevicePixels="true">
<Image Source="pack://application:,,,/LabInOne_ESARS;component/Images/PC/DropDown.png" Width="15" Height="15" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,2,5,0" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ComboBox}, Path=Text}" Value="">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border CornerRadius="4" BorderBrush="{TemplateBinding BorderBrush}" x:Name="templateRoot" BorderThickness="{TemplateBinding BorderThickness}" Background="White" SnapsToDevicePixels="true">
<Image Source="pack://application:,,,/LabInOne_ESARS;component/Images/PC/DropDown.png" Width="15" Height="15" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,2,5,0" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="ComboBoxDeleteTemplate" 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" VerticalOffset="3" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Grid Margin="2" Width="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Grid.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" Opacity="0.8" Color="#bfbfbf" />
</Grid.Effect>
<Border x:Name="dropDownBorder" CornerRadius="4" Width="{TemplateBinding Width}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"
BorderThickness="0" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<ScrollViewer x:Name="DropDownScrollViewer">
<Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
<Canvas x:Name="canvas" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}">
</Rectangle>
</Canvas>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</ScrollViewer>
</Border>
</Grid>
</Popup>
<ToggleButton Cursor="Hand" 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 ComboBoxToggleButtonDelete}" />
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="false" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
<!--水印提示内容-->
<Border Grid.Column="0">
<TextBlock FontSize="12" Name="Message" Visibility="Collapsed" Text="{TemplateBinding Tag}" HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="#999999" IsHitTestVisible="False"
Margin="10,0,0,0" Opacity="1" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true" />
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" />
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}" />
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}" />
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
<Setter TargetName="Message" Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="{x:Null}">
<Setter TargetName="Message" Property="Visibility" Value="Visible" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxEditableDeleteTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" VerticalOffset="3" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Grid Margin="2" Width="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Grid.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" Opacity="0.8" Color="#bfbfbf" />
</Grid.Effect>
<Border x:Name="dropDownBorder" CornerRadius="4" Width="{TemplateBinding Width}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="0"
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<ScrollViewer x:Name="DropDownScrollViewer">
<Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
<Canvas x:Name="canvas" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}">
</Rectangle>
</Canvas>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</ScrollViewer>
</Border>
</Grid>
</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 ComboBoxToggleButtonDelete}" />
<Border x:Name="border" Background="{TemplateBinding Background}" Margin="2">
<TextBox x:Name="PART_EditableTextBox" Margin="2" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxEditableTextBox}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<!--水印提示内容-->
<Border Grid.Column="0">
<TextBlock FontSize="12" Name="Message" Visibility="Collapsed" Text="{TemplateBinding Tag}" HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="#999999" IsHitTestVisible="False"
Margin="10,0,0,0" Opacity="1" />
</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>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
<Setter TargetName="Message" Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="{x:Null}">
<Setter TargetName="Message" Property="Visibility" Value="Visible" />
</DataTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true" />
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" />
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}" />
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="ComboBoxTextStyle" TargetType="{x:Type ComboBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}" />
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="White" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="10,0,0,0" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="FontSize" Value="14" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="MaxDropDownHeight" Value="120" />
<Setter Property="Template" Value="{StaticResource ComboBoxDeleteTemplate}" />
<Setter Property="ItemContainerStyle" Value="{DynamicResource ComboBoxItemStyle}" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Style.Triggers>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Template" Value="{StaticResource ComboBoxEditableDeleteTemplate}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="#00CB7C" />
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="BorderBrush" Value="#BFBFBF" />
</Trigger>
</Style.Triggers>
</Style>
应用
<TextBlock FontSize="14" Text="项目编号:" Width="66" HorizontalAlignment="Left" Margin="650,0,0,0" VerticalAlignment="Center"></TextBlock>
<local1:AutoCompleteComboBox Margin="719,0,0,0" IsEditable="True" x:Name="cbbprojectNoList" Tag="请选择"
Width="140" Height="24" VerticalAlignment="Center" HorizontalAlignment="Left" IsTextSearchEnabled="False"
ItemsSource="{Binding ProjectSearchPa.projectNoList}" KeyUp="CbbprojectNoList_KeyUp" SelectedValue="{Binding ProjectSearchReq.projectNo}"
Style="{StaticResource ComboBoxTextStyle}" SelectionChanged="ComboBoxPro_SelectionChanged" ButtonBase.Click="cbbclassifyList_Click">
</local1:AutoCompleteComboBox>
private void CbbprojectNoList_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
ComboBox combox = sender as ComboBox;
if (combox == null) return;
combox.Tag = null;
string txt = combox.Text;
combox.IsDropDownOpen = false;
vm.查询(查询条件);
TextBox textBox = (TextBox)combox.Template.FindName("PART_EditableTextBox", combox);
combox.Text = txt;
textBox.SelectionStart = textBox.Text.Length;
}
}
private void ComboBoxPro_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
e.Handled = true;
if (!(sender is ComboBox combox)) return;
vm.查询(查询条件);
}
private void cbbclassifyList_Click(object sender, RoutedEventArgs e)
{
var accb = sender as AutoCompleteComboBox;
var cbb = sender as ComboBox;
if (accb == null)
{
if (cbb == null) return;
}
if (accb != null && !string.IsNullOrEmpty(accb.Text))
{
accb.Text = null;
accb.SelectedValue = null;
//vm.GetProjectList_New(vm.ProjectSearchReq);
accb.Tag = "请选择";
accb.IsDropDownOpen = false;
}
else if (cbb != null && !string.IsNullOrEmpty(cbb.Text))
{
cbb.Text = null;
cbb.SelectedValue = null;
//vm.GetProjectList_New(vm.ProjectSearchReq);
cbb.Tag = "请选择";
cbb.IsDropDownOpen = false;
}
else
{
if (accb != null)
accb.IsDropDownOpen = true;
else if (cbb != null)
cbb.IsDropDownOpen = true;
}
}
效果
输入的时候会自动搜索并打开下拉框