简体   繁体   中英

Update C# WPF GUI when different thread and library variable change

I am trying to update GUI when dictionary value changes on WPF, MVVM. Basically, I got following dictionary on separate thread and library/project:

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

A child library/project is a stand-alone application that doesn't know about GUI and won't have one. I try to update GUI from it I would have a project reference issue as GUI project reference to child project, not vice versa. That's why I cannot call GUI from that library using, for example, DispatcherHelper.CheckBeginInvokeOnUI .

GUI however as the main thread should know about child threads. So to achieve that I created an INotifyPropertyChanged Event:

public class ViewModelBase: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

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

I connected it with my MVVM GUI variable

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

My GUI should update whenever Child.ProgressStageDictionary is update. However, my GUI is not catching that. What do I need to change to be able to watch variables updates on child threads?

I found an answer how to do it. I couldn't work out why my Observers does not catch update but I manage to do it using delegators. On the main calculation thread, I create a method that dispatch update to GUI thread:

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

After that when I am calling Project method I delegate MainViewModel method as an action to it.

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

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

Using this solution behind the scene threads are updating/running at following order:

GUI Thread -> Calculation Thread -> Separate Project Thread -> GUI Thread

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM