【问题标题】:Async ComboBox Filtration异步组合框过滤
【发布时间】:2022-09-23 13:42:31
【问题描述】:

我是异步方法的新手并且在这种情况下苦苦挣扎(我举了一个简单的例子来说明我的问题):

假设我有一个 ComboBox,其中的项目与 ***BindableCollection NameList *** 绑定,哪些项目是一些名称。

            <ComboBox
                x:Name=\"SubbranchComboBox\"
                Margin=\"20 0 0 0\"
                Width=\"100\"
                Height=\"20\"
                IsEnabled=\"True\"
                IsEditable=\"True\"
                IsTextSearchEnabled=\"False\"
                InputScope=\"Xml\"
                ItemsSource=\"{Binding NameList}\" KeyUp=\"ComboBox_KeyUp\">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text=\"{Binding}\" />
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>

ComboBox_KeyUp看起来像这样:

        private void ComboBox_KeyUp(object sender, KeyEventArgs e)
    {
        var combobox = (ComboBox)sender;
        var ctb = combobox.Template.FindName(\"PART_EditableTextBox\", combobox) as TextBox;
        if (ctb == null) return;
        if (Keyboard.Modifiers.HasFlag(ModifierKeys.Shift) || Keyboard.Modifiers.HasFlag(ModifierKeys.Control) || Keyboard.Modifiers.HasFlag(ModifierKeys.Alt))
            return;
        var caretPos = ctb.CaretIndex;
        var searchedText = combobox.Text.ToLower();
        combobox.SelectedIndex = -1;
        combobox.IsDropDownOpen = true;

        CollectionView itemsViewOriginal = (CollectionView)CollectionViewSource.GetDefaultView(combobox.Items);
        itemsViewOriginal.Filter = ((o) =>
        {
            if (String.IsNullOrEmpty(searchedText))
            {
                return true;
            }
            else
            {
                if (((string)o).ToLower().Contains(searchedText.ToLower()))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        });
        itemsViewOriginal.Refresh();
        ctb.CaretIndex = caretPos;
    }

并用作搜索功能键入的短语在组合框中。 问题是,我希望异步完成过滤,但每当我尝试这样做时,都会出现错误:调用线程无法访问此对象,因为不同的线程拥有它

请给我一些建议,应该怎么做。 所有示例代码:

    public partial class MainWindow : Window
{
    public BindableCollection<String> NameList { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        NameList = new BindableCollection<String>
            {
                \"Tony\",
                \"Jerry\",
                \"George\",
                \"Harry\",
                \"Snape\",
                \"Sirius\",
                \"Dan\",
                \"Michael\",
                \"Mike\",
                \"Sebastian\",
                \"Simon\",
                \"Johny\"
            };
    }

    private void ComboBox_KeyUp(object sender, KeyEventArgs e)
    {
        var combobox = (ComboBox)sender;
        var ctb = combobox.Template.FindName(\"PART_EditableTextBox\", combobox) as TextBox;
        if (ctb == null) return;
        if (Keyboard.Modifiers.HasFlag(ModifierKeys.Shift) || Keyboard.Modifiers.HasFlag(ModifierKeys.Control) || Keyboard.Modifiers.HasFlag(ModifierKeys.Alt))
            return;
        var caretPos = ctb.CaretIndex;
        var searchedText = combobox.Text.ToLower();
        combobox.SelectedIndex = -1;
        combobox.IsDropDownOpen = true;

        CollectionView itemsViewOriginal = (CollectionView)CollectionViewSource.GetDefaultView(combobox.Items);
        itemsViewOriginal.Filter = ((o) =>
        {
            if (String.IsNullOrEmpty(searchedText))
            {
                return true;
            }
            else
            {
                if (((string)o).ToLower().Contains(searchedText.ToLower()))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        });
        itemsViewOriginal.Refresh();
        ctb.CaretIndex = caretPos;
    }
}

    标签: c# .net wpf wpf-controls


    【解决方案1】:

    问题是,我希望异步完成过滤,但每当我尝试这样做时,都会出现错误:调用线程无法访问此对象,因为不同的线程拥有它

    如果您想从后台线程更新 UI,您应该在应用程序的调度程序中运行代码

    Application.Current.Dispatcher.Invoke(() => /* modify combobox here */);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 2012-11-16
      • 2012-01-26
      相关资源
      最近更新 更多