Текст строки состояния обновления WPF от фонового работника

Это не примитивное значение, поэтому его конструктор и / или деструктор могут иметь желаемые побочные эффекты.

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

class Timed {
    double start;
    public:
        Timed() { start = now(); }
        ~Timed() { std::cout << (now() - start) << '\n'; }
}

Итак, чтобы измерить, сколько времени занимает функция, я просто делаю:

void slow() {
    Timed t;
    // heavy operation here...
}

Переменная t никогда не используется, но она по-прежнему важна к поведению кода.

2
задан kw1jybo 18 March 2019 в 17:03
поделиться

1 ответ

Это общая проблема, с которой люди сталкиваются в WPF. Я полагаю, что вы пытаетесь обновить метку из BackgroundWorker, и вас мучают ошибки "другой поток владеет этим". Вы, вероятно, найдете ответы, в которых вам предлагается использовать диспетчер для обновления вашего ярлыка. НЕ ДЕЛАЙТЕ ЭТОГО! Это ненадежно и часто не обновляется при больших нагрузках. Вы должны использовать правильные методы привязки в вашем случае.

Надеемся, что этот пример (хотя и не обязательно самый рефакторированный, но и не самый быстрый для реализации) может помочь вам начать правильный путь, объяснив некоторые основные принципы или WPF.

Создайте наблюдаемый класс, который реализует INotifyPropertyChanged. Это твоя модель. Это в основном оболочка того, как будут храниться ваши данные (в вашем случае это статус).

using System.ComponentModel;

public class Status_Update : INotifyPropertyChanged 
{
     //private property that stores value
     private string status;

     //public property the gets & sets value
     public string Status
     {
           get {return status;}
           set
           { 
               if(status != value)
               {
                   status = value; 
                   NotifyPropertyChanged("Status");
               } 
           }
     }

     //Logic to notify that property values have changed.
     public event PropertyChangedEventHandler PropertyChanged;
     public void NotifyPropertyChanged(string propName)
     {
         if (PropertyChanged != null)
         {
             PropertyChanged(this, new PropertyChangedEventArgs(propName));
         }
     }

}

Теперь давайте перейдем к коду вашего элемента управления или окна за конструктором.

//Create a Status_Update object in your control.
public Status_Update My_Status {get;set;}

public My_Control_or_Window()
{
       //Initialize the Status_Update object
       MyStatus = new Status_Update(){Status=""};

       InitializeComponent();

       //Set the controls DataContext to itself in the constructor
       DataContext=this;
}

Теперь в XAML вашего веб-интерфейса вы просто привязываетесь к свойству элемента управления MyStatus.Status, и он готов к оперативным обновлениям из любого вызывающего потока.

<Label Content={Binding MyStatus.Status, UpdateSourceTrigger=PropertyChanged}/>

Для обновления просто установите значение MyStatus.Status в BackgroundWorker.

private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
     MyStatus.Status = "Updating the first item";

     Some_Task();

     MyStatus.Status = "Updating the next item";

     Some_Task();
}

Хочу заметить, что этот пример не лучший пример MVVM и не лучшая структура кода для того, что вы пытаетесь сделать, но он должен помочь вам лучше понять, как работает связывание в WPF и о том, как с ним гораздо проще обновлять такие вещи, как метка состояния. Требуется немного больше работы на переднем конце, но экономит так много времени на заднем конце.

Желаем удачи.

0
ответ дан Tronald 18 March 2019 в 17:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: