WPF BackgroundWorker ListView过滤器问题

时间:2009-07-08 14:05:15

标签: .net wpf vb.net listview backgroundworker

我有一个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的示例?

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

绑定到控件的ListCollectionView只能从创建它的线程访问。因此,您只能在UI线程上设置Filter属性...

答案 2 :(得分:0)

正如托马斯在评论中指出的那样,这种方法对于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

ONE BIG WARNING:示例中的“delg”对象还包含一个“Invoke”成员, NOT 您正在寻找的Invoke方法,您需要“Invoke(delg)” ,而不是“delg.Invoke()” - 这就是我提到的歧义