当不同的线程和库变量更改时,更新C#WPF GUI

时间:2019-01-23 14:57:42

标签: c# wpf multithreading mvvm

当WPF,MVVM上的字典值更改时,我正在尝试更新GUI。基本上,我在单独的线程和库/项目上得到以下字典:

 public static Dictionary<string, string> ProgressStageDictionary = new Dictionary<string, string>
    {
        {"Data Initiation", ""},
        {"Data Import", ""}
    };

子库/项目是一个独立的应用程序,它不了解GUI,也没有。我尝试从中更新GUI,我会有一个项目参考问题,作为对子项目的GUI项目参考,反之亦然。这就是为什么我无法使用例如 DispatcherHelper.CheckBeginInvokeOnUI 从该库中调用GUI的原因。

但是,作为主线程的GUI应该了解子线程。为此,我创建了一个 INotifyPropertyChanged 事件:

public class ViewModelBase: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged([CallerMemberName]string caller = null)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(caller));
        }
    }

我将其与MVVM GUI变量连接

        private List<StepItem> _stepItems { get; set; }
        public List<StepItem> StepItems
        {
            get => _stepItems;
            set
            {
                _stepItems = value;
                OnPropertyChanged(nameof(Child.ProgressStageDictionary));
                Thread.Sleep(250);
            }
        }

每当Child.ProgressStageDictionary更新时,我的GUI应该更新。但是,我的GUI并没有抓住这一点。我需要更改什么才能观看子线程上的变量更新?

1 个答案:

答案 0 :(得分:0)

我找到了解决方法。我无法弄清楚为什么我的观察者无法捕获更新,但是我设法使用委托者来完成。 在主计算线程上,我创建了一种将更新分发到GUI线程的方法:

 public void SuperStepProgressMethod(Dictionary<string, string> stepDictionary)
        {
            DispatcherHelper.CheckBeginInvokeOnUI(
                () =>
                {
                    // Set step item list
                    StepItems = StepProgressHandler.UpdateStepList(stepDictionary);
                });
        }

之后,当我调用Project方法时,我将MainViewModel方法委托给它。

 public static void Run(
        Action<Dictionary<string, string>> superStepProgressMethod)
    {

        ProgressStageDictionary["Data Initiation"] = Initiation();
        superStepProgressMethod.Invoke(ProgressStageDictionary);#
    }

在后台使用此解决方案,线程按以下顺序更新/运行:

GUI线程->计算线程->单独的项目线程-> GUI线程