I started to understand WPF, and immediately ran into this problem: there is a variable in the code that I am constantly changing. It is displayed in form in Label. But when you change it in the code in the form, it does not change. How is this generally implemented? In my case, this variable changes in a separate background thread, and it is necessary that it be updated on the screen too.

    1 answer 1

    First, you need the variable that you display on the screen to be part of the DataContext . For example, you put it in a class, and assign a DataContext 'to its instance:

     class VM { public string Message { get; set; } } 
     VM vm = new VM(); 
     window.DataContext = vm; 

    Now you can attach to your property:

     <Label Content="{Binding Message}"/> 

    But that's not all. In order for the window to see the changes to the variable, you must implement the INotifyPropertyChanged interface:

     class VM : INotifyPropertyChanged { string message; public string Message { get { return message; } set { if (message != value) { message = value; NotifyPropertyChanged(); } } } void NotifyPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; } 

    But that's not all. Now for everything to work correctly, you only need to set the value of the VM property in the main thread . How to do it depends on the tools you choose. For example, you can use BeginInvoke in your BeginInvoke . Or perform calculations in the background using async / await techniques.

    • Thank you, almost figured it out. - Ghoul
    • one
      > For example, you can use BeginInvoke in your workflow. What is it like? Well, suppose we do not use commands, then we can call the necessary VM method from the window, for example ((VM)DataContext).МойМетод; Why do BeginInvoke need BeginInvoke ? Give an example, please. - Bulson
    • one
      @Bulson: Well, the TC says its variable is changing in the background thread. So, instead of vm.Message = newValue you need to write dispatcher.BeginInvoke((Action)(() => vm.Message = newValue)); or there dispatcher.InvokeAsync(() => vm.Message = newValue) - VladD
    • @Ghoul: You're welcome! - VladD