Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AutoCompleteTextBox 自动完成控件优化 #1493

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions src/Net_40/HandyControl_Net_40/Themes/Theme.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -11703,19 +11703,20 @@
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="Padding" Value="{StaticResource DefaultInputPadding}" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}" />
<Setter Property="ItemContainerStyle" Value="{StaticResource AutoCompleteTextBoxItemBaseStyle}" />
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}" />
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource AutoCompleteTextBoxItemBaseStyle}" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="hc:Empty.ShowEmpty" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="hc:AutoCompleteTextBox">
<hc:SimplePanel>
<Border CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<TextBox x:Name="PART_SearchTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" CaretBrush="{TemplateBinding CaretBrush}" Padding="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}" />
<TextBox x:Name="PART_SearchTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" CaretBrush="{TemplateBinding CaretBrush}" Padding="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}" Text="{TemplateBinding Text}" />
</Border>
<Popup x:Name="PART_Popup" AllowsTransparency="true" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border BorderThickness="0,1,0,0" Effect="{StaticResource EffectShadow2}" Margin="8,0,8,8" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MinWidth="{Binding ActualWidth, ElementName=toggleButton}" MaxHeight="{TemplateBinding MaxDropDownHeight}" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}">
<Border BorderThickness="0,1,0,0" Effect="{StaticResource EffectShadow2}" Margin="8,0,8,8" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MinWidth="{Binding ActualWidth, ElementName=dropDownBorder}" MaxHeight="{TemplateBinding MaxDropDownHeight}" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}">
<hc:ToggleBlock IsChecked="{Binding HasItems,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch">
<hc:ToggleBlock.CheckedContent>
<ScrollViewer Margin="0,4">
Expand Down Expand Up @@ -11761,7 +11762,18 @@
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style.Triggers>
<Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="DataGridCellStyle" TargetType="DataGridCell">
<Setter Property="FocusVisualStyle">
<Setter.Value>
Expand Down Expand Up @@ -14361,4 +14373,4 @@
</Style>
<Style BasedOn="{StaticResource RangeSliderBaseStyle}" TargetType="hc:RangeSlider" />
<Style BasedOn="{StaticResource SliderBaseStyle}" TargetType="Slider" />
</ResourceDictionary>
</ResourceDictionary>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
xmlns:hc="https://handyorg.github.io/handycontrol"
DataContext="{Binding AutoCompleteTextBoxDemo, Source={StaticResource Locator}}">
<hc:TransitioningContentControl>
<hc:AutoCompleteTextBox Width="380" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="32" ItemsSource="{Binding Items}" Text="{Binding SearchText}" DisplayMemberPath="Name"/>
<hc:AutoCompleteTextBox Width="380" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="32" ItemsSource="{Binding Items}" DisplayMemberPath="Name"/>
</hc:TransitioningContentControl>
</UserControl>
Original file line number Diff line number Diff line change
@@ -1,56 +1,16 @@
using System.Collections.Generic;
using GalaSoft.MvvmLight;
using HandyControl.Collections;
using HandyControlDemo.Data;
using HandyControlDemo.Service;

namespace HandyControlDemo.ViewModel;

public class AutoCompleteTextBoxDemoViewModel : ViewModelBase
{
private string _searchText;

public string SearchText
{
get => _searchText;
#if NET40
set
{
Set(nameof(SearchText), ref _searchText, value);
FilterItems(value);
}
#else
set
{
Set(ref _searchText, value);
FilterItems(value);
}
#endif
}

public ManualObservableCollection<DemoDataModel> Items { get; set; } = new();

private readonly List<DemoDataModel> _dataList;
public List<DemoDataModel> Items { get; set; }

public AutoCompleteTextBoxDemoViewModel(DataService dataService)
{
_dataList = dataService.GetDemoDataList(10);
}

private void FilterItems(string key)
{
Items.CanNotify = false;

Items.Clear();

foreach (var data in _dataList)
{
if (data.Name.ToLower().Contains(key.ToLower()))
{
Items.Add(data);
}
}

Items.CanNotify = true;
Items = dataService.GetDemoDataList(10);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Windows;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using HandyControl.Data;
Expand All @@ -15,8 +16,6 @@ public class AutoCompleteTextBox : ComboBox

private System.Windows.Controls.TextBox _searchTextBox;

private object _selectedItem;

static AutoCompleteTextBox()
{
TextProperty.OverrideMetadata(typeof(AutoCompleteTextBox), new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
Expand All @@ -40,18 +39,14 @@ public override void OnApplyTemplate()
_searchTextBox.PreviewKeyDown += SearchTextBoxKeyDown;
_searchTextBox.TextChanged += SearchTextBoxTextChanged;
}

UpdateTextBoxBySelectedItem(_selectedItem);
}

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

if (e.AddedItems.Count > 0)
{
_selectedItem = e.AddedItems[0];
UpdateTextBoxBySelectedItem(_selectedItem);
var selectedItem = e.AddedItems[0];
UpdateTextBoxBySelectedItem(selectedItem);
}
}

Expand All @@ -61,7 +56,6 @@ protected override void OnSelectionChanged(SelectionChangedEventArgs e)

private void SearchTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
_selectedItem = null;
SelectedIndex = -1;

if (ignoreTextChanging)
Expand All @@ -78,6 +72,7 @@ private void SearchTextBoxTextChanged(object sender, TextChangedEventArgs e)
}
else if (_searchTextBox.IsFocused)
{
Items.Filter = FilterItem ?? DefaultFilter;
SetCurrentValue(IsDropDownOpenProperty, ValueBoxes.TrueBox);
}
}
Expand Down Expand Up @@ -152,7 +147,17 @@ private void SearchTextBoxGotFocus(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(Text))
{
Items.Filter = FilterItem ?? DefaultFilter;
SetCurrentValue(IsDropDownOpenProperty, ValueBoxes.TrueBox);
}
}


public Predicate<object> FilterItem { get; set; }

private bool DefaultFilter(object item)
{
var text = BindingHelper.GetString(item, DisplayMemberPath);
return text.ToLower().Contains(Text.ToLower());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
<Setter Property="Padding" Value="{StaticResource DefaultInputPadding}"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource AutoCompleteTextBoxItemBaseStyle}"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="hc:Empty.ShowEmpty" Value="True"/>
Expand All @@ -60,10 +61,10 @@
<ControlTemplate TargetType="hc:AutoCompleteTextBox">
<hc:SimplePanel>
<Border CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<TextBox x:Name="PART_SearchTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" CaretBrush="{TemplateBinding CaretBrush}" Padding="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}"/>
<TextBox x:Name="PART_SearchTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" CaretBrush="{TemplateBinding CaretBrush}" Padding="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}" Text="{TemplateBinding Text}" />
</Border>
<Popup x:Name="PART_Popup" AllowsTransparency="true" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border BorderThickness="0,1,0,0" Effect="{StaticResource EffectShadow2}" Margin="8,0,8,8" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MinWidth="{Binding ActualWidth, ElementName=toggleButton}" MaxHeight="{TemplateBinding MaxDropDownHeight}" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}">
<Border BorderThickness="0,1,0,0" Effect="{StaticResource EffectShadow2}" Margin="8,0,8,8" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MinWidth="{Binding ActualWidth, ElementName=dropDownBorder}" MaxHeight="{TemplateBinding MaxDropDownHeight}" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}">
<hc:ToggleBlock IsChecked="{Binding HasItems,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch">
<hc:ToggleBlock.CheckedContent>
<ScrollViewer Margin="0,4">
Expand Down Expand Up @@ -109,6 +110,17 @@
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

</ResourceDictionary>
16 changes: 14 additions & 2 deletions src/Shared/HandyControl_Shared/Themes/Theme.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -11840,6 +11840,7 @@
<Setter Property="Padding" Value="{StaticResource DefaultInputPadding}" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}" />
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True" />
<Setter Property="ItemContainerStyle" Value="{StaticResource AutoCompleteTextBoxItemBaseStyle}" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="hc:Empty.ShowEmpty" Value="True" />
Expand All @@ -11848,10 +11849,10 @@
<ControlTemplate TargetType="hc:AutoCompleteTextBox">
<hc:SimplePanel>
<Border CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<TextBox x:Name="PART_SearchTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" CaretBrush="{TemplateBinding CaretBrush}" Padding="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}" />
<TextBox x:Name="PART_SearchTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" CaretBrush="{TemplateBinding CaretBrush}" Padding="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}" Text="{TemplateBinding Text}" />
</Border>
<Popup x:Name="PART_Popup" AllowsTransparency="true" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border BorderThickness="0,1,0,0" Effect="{StaticResource EffectShadow2}" Margin="8,0,8,8" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MinWidth="{Binding ActualWidth, ElementName=toggleButton}" MaxHeight="{TemplateBinding MaxDropDownHeight}" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}">
<Border BorderThickness="0,1,0,0" Effect="{StaticResource EffectShadow2}" Margin="8,0,8,8" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MinWidth="{Binding ActualWidth, ElementName=dropDownBorder}" MaxHeight="{TemplateBinding MaxDropDownHeight}" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}">
<hc:ToggleBlock IsChecked="{Binding HasItems,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch">
<hc:ToggleBlock.CheckedContent>
<ScrollViewer Margin="0,4">
Expand Down Expand Up @@ -11897,6 +11898,17 @@
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="DataGridCellStyle" TargetType="DataGridCell">
<Setter Property="FocusVisualStyle">
Expand Down