Можно ли обновить элементы UI страницы из другого класса? (WPF)

Вопрос или проблема

Изначально проблема заключалась в вопросе “Как обновить элементы UI из другого класса?”, которую я решил с помощью

public static MainWindow window
{
    get
    {
        return Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
    }
}

используя строку типа “MainWindow.window.(элемент ui для обновления);” для обновления элемента UI

Я решил попробовать добавить страницы в свое приложение, что я и сделал с помощью

public MainWindow()
{
    AssemblerGUI assemblerWindow = new AssemblerGUI();
    NavigationFrame.Navigate(assemblerWindow);
}

(NavigationFrame – это название элемента Frame в xaml)

Страницы работают, но вышеуказанное решение, позволяющее другим классам изменять UI, не работает и выбрасывает “Ссылка на объект не задана для объекта экземпляра” каждый раз, когда оно вызывается, из-за того, что страница создается для перехода к ней в фрейме.

Я догадался, что мог бы просто поместить весь код в файл .xaml.cs страницы, но это было бы довольно раздражающе для меня в будущем, когда я буду добавлять функции.

Я попробовал свое предыдущее решение, но оно выбрасывает ошибку, когда страница создается (и должна создаваться для работы XAML)

public static AssemblerGUI page
{
    get
    {
        return Application.Current.Windows.OfType<AssemblerGUI>().FirstOrDefault();
    }
}

Ответ или решение

Да, обновление элементов пользовательского интерфейса (UI) из другого класса в WPF возможно, но требует использования правильного подхода для обеспечения связи между классами и актуальным состоянием UI. Ваш первоначальный метод, использующий статическое свойство для доступа к окну, не будет работать в случае с навигацией за пределами основного окна в новую страницу. Давайте рассмотрим более подходящий способ.

Подход с использованием событий и делегатов

  1. Создание событий в вашей странице: Создайте событие на странице, которое будет вызываться, когда необходимо обновить UI. Это позволит другим классам подписаться на это событие и получать уведомления.
public partial class AssemblerGUI : Page
{
    // Событие для обновления UI
    public event EventHandler<string> UpdateUiRequested;

    public AssemblerGUI()
    {
        InitializeComponent();
        // Подписка на событие, если это необходимо
        UpdateUiRequested += OnUpdateUiRequested;
    }

    private void OnUpdateUiRequested(object sender, string message)
    {
        // Обновите ваш UI элемент здесь
        myTextBox.Text = message;
    }

    public void RequestUpdateUI(string message)
    {
        UpdateUiRequested?.Invoke(this, message);
    }
}
  1. Использование события в другом классе: В вашем другом классе вы можете получить доступ к экземпляру AssemblerGUI, и по мере необходимости вызывать метод RequestUpdateUI.
public class SomeOtherClass
{
    private AssemblerGUI assemblerPage;

    public SomeOtherClass(AssemblerGUI page)
    {
        assemblerPage = page;
    }

    public void UpdateAssemblerPage()
    {
        // Запрос на обновление UI
        assemblerPage.RequestUpdateUI("Обновленное сообщение");
    }
}
  1. Передача экземпляра страницы между классами: Убедитесь, что вы передаете экземпляр страницы, когда создаете другой класс. Например, в вашем MainWindow:
public MainWindow()
{
    InitializeComponent();
    AssemblerGUI assemblerWindow = new AssemblerGUI();
    NavigationFrame.Navigate(assemblerWindow);

    // Создание другого класса и передача экземпляра страницы
    SomeOtherClass otherClass = new SomeOtherClass(assemblerWindow);
    otherClass.UpdateAssemblerPage(); // Пример вызова обновления
}

Другие рекомендации

  • MVVM Паттерн: Подумайте о применении паттерна MVVM (Model-View-ViewModel), который в WPF является стандартом. Этот подход разъединяет логику приложения и UI, позволяя следить за изменениями через через INotifyPropertyChanged.

  • Основной поток UI: WPF требует, чтобы все изменения UI происходили в основном потоке интерфейса. Если вы вызываете ваши методы из фоновых потоков, убедитесь, что вы вызываете их на UI-потоке.

Используя эти методы, вы сможете организовать обновление UI из разных классов более чисто и не нарушая принципы проектирования. Это также значительно упростит добавление новых функций в будущем.

Оцените материал
Добавить комментарий

Капча загружается...