Текст строки состояния обновления WPF от фонового работника - PullRequest
2 голосов
/ 18 марта 2019

У меня есть строка состояния в окне, которую я хочу обновить строкой во время фонового процесса.

В частности, пользователь нажимает кнопку, и данные считываются из файла.Когда файл читается, выполняются внутренние вызовы БД для заполнения объектов данных.Это делается для всех строк в файле.Это может занять немного времени. Все это делается в фоновом режиме.

Что я хочу сделать, так это дать пользователю ощущение, что что-то происходит.Я хотел бы предоставить пользователю имя объекта, который был только что прочитан в строке состояния.Я вижу, что BackgroundWorker предоставляет значение обновления промежуточного значения, но как мне сделать строку, чтобы я мог ее отобразить?

1 Ответ

2 голосов
/ 18 марта 2019

Это распространенная проблема, с которой люди сталкиваются в 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 и как вы можете с ней гораздо проще обновлять такие вещи, как метка статуса. Требуется немного больше работы на переднем конце, но экономит так много времени на заднем конце.

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...