0

我有一个 WPF ListView,我试图在 BackgroundWorker 中进行过滤。我的代码如下所示:

Dim Worker As New BackgroundWorker
AddHandler Worker.DoWork, AddressOf Me.FilterAsync
Me.TextBoxText = Me.TextBox.Text
Worker.RunWorkerAsync(Me.TextBox)

Private Sub FilterAsync(ByVal sender As Object, ByVal e As DoWorkEventArgs)
    '
    Dim BackgroundWorker As BackgroundWorker = CType(sender, BackgroundWorker)
    Dim Text As String = e.Argument.ToString
    '
    Dim ListView As ListCollectionView = CType(CollectionViewSource.GetDefaultView(Me.ListView.ItemsSource), ListCollectionView)
    If Text <> String.Empty Then
        ListView.Filter = New Predicate(Of Object)(AddressOf Me.FindItemsAsync)
    Else
        ListView.Filter = Nothing
    End If
    '
End Sub

此代码通过过滤运行,但失败并显示错误“调用线程无法访问此对象,因为不同的线程拥有它。” 在以下行:

ListView.Filter = New Predicate(Of Object)(AddressOf Me.FindItemsAsync)

这里会有什么问题?我似乎找不到任何通过 BackgroundWorker 过滤的样本。

更新:有谁知道使用 BackgroundWorker 过滤 WPF ListView 的示例?

4

3 回答 3

1

我想运行过滤器需要很长时间,所以你想在后台线程中运行过滤代码——这是不可能的。

与 UI 对话的代码(包括设置过滤器和过滤器内的代码)必须在 UI 线程中运行。

您可以做的是,在 BackgroundWorker 代码中,创建一个新列表,其中仅包含应过滤的项目,然后在 BackgroundWorker 完成并且您返回 UI 线程后,将新列表设置为 ListView 的 ItemSource .

于 2009-10-28T12:12:11.020 回答
0

绑定到控件的 AListCollectionView只能从创建它的线程访问。所以你只能Filter在UI线程上设置属性......

于 2009-07-08T15:16:32.213 回答
0

正如 Thomas 在评论中指出的那样,这种方法对于 WPF 来说完全是废话,它是 WinForms 方法

基于 Thomas 的回答,如果后台线程需要更新 UI,那么它需要首先切换到创建 UI 的线程。

为简单起见,您可以考虑一个“UI 线程”,然后是“后台线程”。UI 线程负责将内容绘制到屏幕上、处理用户交互等......从后台线程调用修改 UI 可能会导致各种混乱,因此从 .NET 2.0(或者可能是 1.1)开始是默认的行为是抛出异常而不是允许潜在危险的调用成功。

通常(至少在 2.0 世界中)您通过“调用”您需要更新的表单/控件来执行此操作,“调用”在框架中有点模棱两可,但在 UI 控件的上下文中它意味着“返回到UI 线程”。

在 2.0 中,用于执行此操作的典型模式如下:

Private DelegateSub UpdateSomeUICaller()
Private Sub UpdateSomeUI()
    If Me.InvokeRequired Then
        Dim delg as new UpdateSomeUICaller(AddressOf UpdateSomeUI)
        Me.Invoke(delg)
        Exit Sub
    End If

    Me.SomeUiControl.Text = "Hello from the UI Thread!"

End Sub

一个大警告:示例中的“delg”对象还包含一个“Invoke”成员,这不是您要查找的 Invoke 方法,您需要“Invoke(delg)”,而不是“delg.Invoke()”- -这就是我提到的模棱两可

于 2009-07-08T15:32:23.570 回答