Wpf MVVM: не удалось обновить значение метки с помощью synchronizationcontext
Я открываю окно WPF из приложения Winforms в manuItem_ClickedHandler.
Шаг 1:
В конструкторе ViewModel я создаю поток и выполняю некоторую работу. В случае обратного вызова значение элемента управления успешно обновляется.
Шаг 2:
Я закрываю эту форму WPF и снова открываю окно WPF. Поток снова запускается и завершает свою работу, но на этот раз текст в графическом интерфейсе WPF не обновляется. Обратный вызов вызывается. но никакой ошибки и никакого обновления графического интерфейса.
Что я уже пробовал:
модель представления
public class MyViewModel : BindableBase { internal ThreadClass objThreadClass; string statusText = $"The Time is: {DateTime.Now}"; public SynchronizationContext ViewContext; public string StatusText { get => statusText; set => SetProperty(ref statusText, value); } public MyViewModel() { objThreadClass = new ThreadClass(); Events_Delegates.evDisplayStatus += Events_Delegates_evDisplayStatus; } void Events_Delegates_evDisplayStatus(int count) { ViewContext.Post(x => StatusText = $"Current Count is: {count}"); } }
//ThreadClass
//
public class ThreadClass { Thread objThread; Events_Delegates EvDel = new Events_Delegates(); public ThreadClass() { objThread = new Thread(ExecuteMethod); objThread.Start(); } void ExecuteMethod() { int i = 0; int j = 0; while (true) { while (i < 1000) { i++; } i = 0; j++; EvDel.DisplayStatus(j); Thread.Sleep(500); } } } public class Events_Delegates { public delegate void dUpdateStatus(int count); public static event dUpdateStatus evDisplayStatus; public void DisplayStatus(int count) { evDisplayStatus(count); } }
//Смотреть
<pre><Window x:Class="Abc.View.WinMultiThread" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Abc.View" xmlns:dc="clr-namespace:Abc.ViewModel" mc:Ignorable="d" Title="Multi Threading" Height="1200" Width="2000" WindowState="Maximized" > <Window.DataContext> <dc:My_ViewModel/> </Window.DataContext> <Grid> <Label Grid.Column="1" FontSize="18" FontWeight="Bold" Foreground="White" Background="OrangeRed" VerticalAlignment="Center" Content="{Binding StatusText}" ></Label> </Grid> </Window>
//с фоновым кодом
public partial class WinMultiThread : Window { My_ViewModel dataContext = null; public WinDashboard() { InitializeComponent(); dataContext = (My_ViewModel)this.DataContext; dataContext.ViewContext = SynchronizationContext.Current; //Assigning Context to update GUI that will be used in ViewModel } }
//Код для открытия формы Wpf с помощью кнопки Winform
Abc.View.WinMultiThread wpfwindow = new Abc.View.WinMultiThread(); ElementHost.EnableModelessKeyboardInterop(wpfwindow); wpfwindow.Show();
Gerry Schmitz
Я не вижу никакого кода "On property changed". Недопустимые привязки все еще могут работать "один раз".
DoingWork
Насколько мне известно, при реализации BindableBase в модели View затем SetProperty(ref statusText, value); метод в Setter вызывает On_property_changed в фоновом режиме.
Richard Deeming
У вас есть утечка памяти в вашем приложении. Статика evDisplayStatus
поле имеет ссылку на ваш MyViewModel
экземпляр, который никогда не освобождается при закрытии окна.
Непонятно, почему вы вообще используете этот класс, а не вызываете событие непосредственно из вашего компьютера. ThreadClass
класс.