Как отслеживать изменение переменной

Есть 3 класса из которых в реальном времени будут вноситься изменения в переменную. Есть TextBlock в который нужно с новой строки выводить содержимое этой переменной каждый раз когда она изменяется. TextBlock находится во втором созданном xaml окне, который еще НЕ ЗАПУЩЕН. Окно вызывается каждый раз нажатием на кнопку по нажатию выполняется window.Show(). То есть каждый раз открывается новое окно. И это окно якобы должно подключаться к трансляции переменной, якобы начать следить за изменениями этой переменной.


Ответы (2 шт):

Автор решения: Programmer

Какое решение мне подошло:

Класс где будет изменяться переменная:

class StatusInfo : INotifyPropertyChanged
{
    public string status;

    public string Status
    {
        get
        {
            return status;
        }
        set
        {
            status = value;
            OnPropertyChanged("Status");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string PropertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
}

Класс куда я буду отправлять класс с переменной которая будет изменяться, он нужен для второго окна, которое запуститься когда захочет пользователь и будет проверять есть ли что-то или нет, а также классы в которых я буду изменять эту переменную смогут брать отсюда этот класс, чтобы потом менять в нем переменную:

class StatusGet
{
    public static StatusInfo status = null;
}

Дальше мое основное окно, которое запускается сразу как только запускается программа будет передавать в класс StatusGet класс StatusInfo:

var st = new StatusInfo();
StatusGet.status = st;

После, во втором окне, которое запускается пользователем подхватывает эту переменную вот так:

public Status()
{
    InitializeComponent();
    GetInfo();
}

public void GetInfo()
{
    if (StatusGet.status != null)
    {
        try
        {
            DataContext = StatusGet.status;
        }
        catch (Exception e)
        {
            Task.Run(async () =>
            {
                await Task.Delay(1000);
                GetInfo();
            });
        }
    }
    else
    {
        Task.Run(async () =>
        {
            await Task.Delay(1000);
            GetInfo();
        });
    }
}
→ Ссылка
Автор решения: aepot

Берём вашу вьюмодель, я только немного поравлю

class StatusInfo : INotifyPropertyChanged
{
    private string status;

    public string Status
    {
        get => status;
        set
        {
            status = value;
            OnPropertyChanged(nameof(Status));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Берём окно с таким содержимым в XAML

<TextBlock Text="{Binding Status}" />

В код окна не пишем вообще ничего, пусть там будет то что было по умолчанию.

Теперь создаём вьюмодель один раз

private readonly StatusInfo statusInfo = new StatusInfo();
private Dispatcher dispatcher; // для многопоточности, если надо

Теперь где-то в коде создаём окно

Window window = new StatusWindow();
window.DataContext = statusInfo;

dispatcher = window.Dispatcher;
window.Closing += (s, e) => dispatcher = null;

window.Show();

Далее просто в коде меняем

statusInfo.Status = "Hello World";

И готово.

Если работа идёт в многопоточном режиме, то можно вот так выполнить код в потоке окна:

dispatcher?.Invoke(() => { statusInfo.Status = "Hello World"; });

Есть решения покрасивее типа Progress<T>, но это самое простое.

→ Ссылка