Scenario: 我正在使用过滤功能在WPF中实现自定义组合: Combobox包含一个带有用于过滤的文本框的弹出窗口。 在文本框下方,列表仅显示垫子...

问题描述 投票:0回答:0
我在WPF中实现具有过滤功能的自定义

ComboBox

ComboBox
包含一个用于过滤的

Popup
    。 the the
  • TextBox
    ,列表仅显示匹配过滤器文本的项目。
    如果其文本包含过滤器文本,则一个项目仍然可见。
    不匹配的indems使用
    TextBox
    隐藏,这是通过
    Visibility.Collapsed
    和转换器应用的。
    
  • 找到底部的完整实现。
  • sissue:
  • 当总数的总数(在过滤之前)
  • 在140
    以下时,一切正常:
    typing在
  • ItemContainerStyle
中动态过滤列表。

删除字符的行为如预期的。

,但是,当总数的总数超过150时,当删除字符中的字符:

时会发生奇怪的行为。

如果我键入TextBox,过滤正常工作。 ,然后,如果我仅删除

TextBox
    ,则
  • "1a"
    将不反应:
    
  • 光标不会重置其预期位置 - 在光标的位置下方的屏幕截图中,应该是左侧的一个字符,但是删除字符后它仍然位于错误的位置。

left/右箭头键盘导航停止工作。 然后,如果我删除“ 1”光标正确重置,并且一切再次起作用。


    问题:
  • 我的要求是,在所有情况下,都按预期行事。我发现这种光标行为非常出乎意料和不寻常。
    
  • 是什么导致这种行为?
  • 我如何通过以下限制来解决此行为:
    
    解决方案不应涉及虚拟化the
    "a"
  • 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
          
      
      
wpf xaml combobox
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.