использование делегата для обновления информации метки wpf из другого класса

1

У меня есть окно Wpf и соответствующий ViewModel. На MainWindow есть метка, привязанная к свойству CurrentActionTaken

private string _CurrentActionTaken;
public string CurrentActionTaken
{
   get{
         return _CurrentActionTaken;
   }
   set{
        _CurrentActionTaken = value;
        OnPropertyChanged("CurrentActionTaken");
   }
}

У меня есть BackgroundWorker который вызывает частный метод WorkerDoWork внутри той же viewmodel

_Worker = new BackgroundWorker();
...
_Worker.DoWork += (obj, e) => WorkerDoWork(_selectedEnumAction, _SelectedCountry);
_Worker.RunWorkerAsync();

Внутри WorkerDoWork Я хочу вызвать другой класс, который займет тяжелую работу, и я хочу отображать CurrentActionTaken обрабатываемый элемент на ярлыке MainWindow (привязанный к свойству CurrentActionTaken)

private void WorkerDoWork(Enums.ProviderAction action, CountryCombo selCountry) 
{
    _CurrentActionTaken = "entered WorkerDoWork method";
    OnPropertyChanged("CurrentActionTaken");
    new MyOtherClass(_selectedEnumAction, _SelectedCountry);
    ...
}

здесь я думал использовать метод, который будет вызван OtherClass итерации данных OtherClass:

public static void DataProcessUpdateHandler(string item)
{
   MessageBox.Show(item);
}

и, наконец, звоните с итерации где-то в OtherClass:

foreach (var item in items)
{                    
    ...
    MainViewModel.DataProcessUpdateHandler(item.NameOfProcessedItem);
}

Все работает с отображением элемента внутри MessageBox в DataProcessUpdateHandler

MessageBox.Show(item);

Мой вопрос в том, как это изменить и использовать

_CurrentActionTaken = item;
OnPropertyChanged("CurrentActionTaken");

В настоящее время это невозможно, так как DataProcessUpdateHandler является статическим методом.

Теги:
wpf

1 ответ

1
Лучший ответ

Вот быстрый и грязный способ:

(Application.Current.MainWindow.DataContext as MainViewModel).CurrentActionTaken = "Executing evil plan to take control of the world."

Конечно, вы должны адаптироваться, если ваш MainViewModel доступен через свойство внутри MainWindow:

Application.Current.MainWindow.Model.CurrentActionTaken = "Executing evil plan to take control of the world."

"Правильный" способ состоял бы в том, чтобы обойти вашу модель взгляда (или любой другой промежуточный объект), но если вы хотите, чтобы все было просто и можно использовать вышеупомянутый метод, тогда ИМХО бесполезно делать более сложные вещи.

РЕДАКТИРОВАТЬ: по вашему требованию быть более чистым вы можете обойти виртуальную машину:

private void WorkerDoWork(Enums.ProviderAction action, CountryCombo selCountry) 
{
    _CurrentActionTaken = "entered WorkerDoWork method";
    OnPropertyChanged("CurrentActionTaken");
    new MyOtherClass(_selectedEnumAction, this);
    ...
}

И экземпляр MyOtherClass будет иметь доступ ко всей виртуальной _SelectedCountry: _SelectedCountry и CurrentActionTaken.

Вы можете пойти дальше, ISupportCurrentActionTaken интерфейс ISupportCurrentActionTaken чтобы отделить MyOtherClass от MainViewModel но если они живут в одном проекте, это явно завышает.

  • 0
    спасибо, можете ли вы порекомендовать мне какое-нибудь лучшее решение для этого (имея в виду мой вопрос), которое может быть более сложным в целом, но проще в обслуживании.
  • 0
    @ user1765862 Я отредактировал свой ответ с деталями.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню