gpt4 book ai didi

后台线程中的 WPF 更新绑定(bind)

转载 作者:行者123 更新时间:2023-12-03 13:55:37 25 4
gpt4 key购买 nike

我有一个控件,它的数据绑定(bind)到标准 ObservableCollection ,我有一个后台任务调用服务来获取更多数据。

然后,我想在我的控件后面更新我的支持数据,同时显示“请稍候”对话框,但是当我将新项目添加到集合中时,UI 线程在重新绑定(bind)和更新我的控件时锁定。

我可以解决这个问题,以便我的动画和内容继续在我的“请稍候”对话框中运行吗?

或者至少给用户一个它没有被锁定的“外观”?

最佳答案

我有一个运行工作线程并将事件发送回应用程序的 DLL - 在 Windows 窗体上完美运行,切换到 WPF 并且一切都停止工作。我已经把头撞在砖墙上了 4 个小时,试图让它发挥作用。但是由于微软的 UI 线程安全编码 EnableCollectionSynchronization,我最终得到的解决方案提供了一个非常干净的实现来解决这个问题。

此集合扩展 ObservableCollection 并实现 EnableCollectionSynchronization 使这些对象可在 WPF 和后台工作人员之间使用。

编辑 : Microsoft's docs说以下,所以我将假设对象上下文共享无关紧要。

The context parameter is an arbitrary object that you can use to information known when you enable collection synchronization. Context can be null.



ThreadSafeCollection.cs
using System.Collections.ObjectModel;
using System.Windows.Data;

namespace NSYourApplication
{
/// <summary>
/// This ObservableCollection is thread safe
/// You can update it from any thread and the changes will be safely
/// marshalled to the UI Thread WPF bindings
/// Thanks Microsoft!
/// </summary>
/// <typeparam name="T">Whatever type of collection you want!</typeparam>
public class ThreadSafeCollection<T> : ObservableCollection<T>
{
private static object __threadsafelock = new object();

public ThreadSafeCollection()
{
BindingOperations.EnableCollectionSynchronization(this, __threadsafelock);
}
}
}

示例 WindowViewModel
WindowViewModel.cs
namespace NSYourApplication
{
/// <summary>
/// Example View
/// BaseModelView implements "PropertyChanged" to update WPF automagically
/// </summary>
class TestViewModel : BaseModelView
{
public ThreadSafeCollection<string> StringCollection { get; set; }

/// <summary>
/// background thread implemented elsewhere...
/// but it calls this method eventually ;)
/// Depending on the complexity you might want to implement
/// [MethodImpl(MethodImplOptions.Synchronized)]
/// to Synchronize multiple threads to prevent chase-conditions,deadlocks etc
/// </summary>
public void NonUIThreadMethod()
{
// No dispatchers or invokes required here!
StringCollection.Add("Some Text from a background worker");
}

/// <summary>
/// Somewhere in the UIThread code it'll call this method
/// </summary>
public void UIThreadMethod()
{
StringCollection.Add("This text come from UI Thread");
}

/// <summary>
/// Constructor, creates a thread-safe collection
/// </summary>
public TestViewModel()
{
StringCollection = new ThreadSafeCollection<string>();
}
}
}

xaml 窗口/控件中列表框中的用法
MainWindow.xaml
    <ListBox x:Name="wpfStringCollection" ItemsSource="{Binding StringCollection,Mode=OneWay}">

</ListBox>

关于后台线程中的 WPF 更新绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2505492/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com