2

我是 WPF、MVVM 和 MVVMLight 的菜鸟,你能帮我解决一些对我的项目非常重要的事情吗?我需要从视图模型创建的不同线程更新视图中的集合。我的 ViewModel 完全不知道 View。我在我的视图模型中定义了一个可观察的集合:

public class LoginViewModel: ViewModelBase
{
    public ObservableCollection<DatabaseConfiguration> DatabaseConfigurations{ get; set; }

    private DatabaseConfiguration _dbConfig;

    public DatabaseConfiguration DbConfig
    {
        get{return _dbConfig;}
        set
        {
        _dbConfig=value;
        RaisePropertyChanged(()=>DbConfig);
        }
    }

我使用 System.threading.Task 回调将一个项目从视图模型添加到集合中:

    void AddDBConfig(DatabaseConfiguration config)
    {
        Task<bool> asyncTask = Task.Factory.StartNew<bool>(
        () =>
        {
        return DatabaseUtility.ValidateDatabaseConnectionConfiguration(config);
        });        

        ExecuteAsync(asyncTask,
            (IAsyncResult ar) =>
            {
                Task<bool> t1 = (Task<bool>)ar;
                if (!t1.IsFaulted)
                {
                    if (!(bool)result)
                    {
                    //problematic statement
                    DatabaseConfigurations.Add(config);
                    }                    
                }
            }); 
    }

    public void ExecuteAsync(Task<object> asyncTask, AsyncCallback callback)
    {
        asyncTask.ContinueWith(task => callback(asyncTask));
        asyncTask.Start();
    }        
}

我在执行时收到以下错误:

“这种类型的 CollectionView 不支持从不同于 Dispatcher 线程的线程更改其 SourceCollection”

MVVMLight 工具包中是否有任何解决方法或内置机制来从不同的线程更新 UI 集合?

您的帮助将是一个很大的帮助!!!谢谢!

4

3 回答 3

2

ContinueWith()有一个接受 TaskScheduler 的重载。wpf 和 winforms 有特殊的调度程序。您可以拨打电话获取TaskScheduler.FromCurrentSynchronizationContext()

在这里阅读。

SalientBrain 的回答也是正确的。

于 2012-12-02T08:40:30.850 回答
0
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
    //(non)problematic statement
    DatabaseConfigurations.Add(config);
    //or perform creating of ObservableCollection
});
于 2012-12-02T08:15:06.843 回答
0

Mvvm light 有一个调度程序助手类来处理它。请参阅DispatcherHelper 的简单示例

首先,在视图模型构造函数中初始化 DispatcherHelper。

DispatcherHelper.Initialize(); 

然后,使用 CheckBeginInvokeOnUI 从 ui 线程运行。

DispatcherHelper.CheckBeginInvokeOnUI(
    () => DatabaseConfigurations.Add(config)
);

请注意,使用 mvvm light,属性更新会自动在 ui 线程上运行。只有集合需要调度程序辅助方法。

于 2013-11-07T07:04:41.033 回答