ComboBox
:
ComboBox
包含一个用于过滤的Popup
TextBox
,列表仅显示匹配过滤器文本的项目。 如果其文本包含过滤器文本,则一个项目仍然可见。 不匹配的indems使用
TextBox
隐藏,这是通过
Visibility.Collapsed
和转换器应用的。
sissue:
以下时,一切正常:typing在
ItemContainerStyle
删除字符的行为如预期的。
,但是,当总数的总数超过150时,当删除字符中的字符::
时会发生奇怪的行为。
如果我键入TextBox
,过滤正常工作。
,然后,如果我仅删除
TextBox
"1a"
将不反应:
left/右箭头键盘导航停止工作。 然后,如果我删除“ 1”光标正确重置,并且一切再次起作用。
我的要求是,在所有情况下,都按预期行事。我发现这种光标行为非常出乎意料和不寻常。
我如何通过以下限制来解决此行为:
解决方案不应涉及虚拟化the
"a"
TextBox
。
TextBox
ComboBox
VirtualizingStackPanel
我通常会将其作为评论,我意识到这不符合您对您对的要求:“解决方案不应包括任何代码更改 - 必须仅是XAML的更改”。比我以这种格式合理显示的代码要多得多。
说,我注意到的是,<Window x:Class="FilterableComboBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FilterableComboBox"
Title="MainWindow"
Height="100"
Width="400">
<Window.Resources>
<local:StringContainsConverter x:Key="StringContainsConverter" />
</Window.Resources>
<Grid>
<ComboBox x:Name="FilterableComboBox"
HorizontalAlignment="Stretch"
Height="25"
Width="300"
ItemsSource="{Binding CustomValues}">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="Visibility">
<Setter.Value>
<MultiBinding Converter="{StaticResource StringContainsConverter}">
<Binding />
<Binding ElementName="FilterTextBox" Path="Text" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
<ComboBox.Template>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton Content="{TemplateBinding SelectedItem}"
IsChecked="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" />
<Popup x:Name="Popup"
Width="{Binding ElementName=FilterableComboBox, Path=ActualWidth}"
IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"
MaxHeight="200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0"
x:Name="FilterTextBox"
HorizontalAlignment="Stretch" />
<ScrollViewer Grid.Row="1"
Background="White">
<ItemsPresenter />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</ComboBox.Template>
</ComboBox>
</Grid>
</Window>
可能会进行更强大的类型检查,并且由于在此过滤中会突出特征,因此确保没有一些意外输入可能是谨慎的。这里可能会在UI线程中的一个尴尬时刻发生一个例外,并负责冻结。例如,在数组值上进行明确的铸造
using System.ComponentModel;
using System.Windows;
namespace FilterableComboBox
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public MainViewModel()
{
_customValues = new List<string>();
for (int i = 0; i < 500; i++)
_customValues.Add(i.ToString());
}
private string _filterText = string.Empty;
public string FilterText
{
get
{
return _filterText;
}
set
{
_filterText = value;
OnPropertyChanged(nameof(FilterText));
}
}
private IList<string> _customValues;
public IList<string> CustomValues
{
get
{
return _customValues;
}
set
{
_customValues = value;
OnPropertyChanged(nameof(CustomValues));
}
}
}
}
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace FilterableComboBox
{
public class StringContainsConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter,CultureInfo culture)
{
string text = (string)values[0];
string filterText = (string)values[1];
return text.Contains(filterText)
? Visibility.Visible
: Visibility.Collapsed;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
IValueConverter