DoingWork Ответов: 0

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 класс.

0 Ответов