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

2

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

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

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

  • 1
    У вас есть примеры кода? Это WPF или WinForms?
  • 1
    Это WPF. И нет, у меня нет примеров кода, потому что я знаю, что ReportProgress / ProgressPercentage недостаточно для того, что мне нужно.
Показать ещё 1 комментарий
Теги:
wpf

1 ответ

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

Это общая проблема, с которой люди сталкиваются в 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));
         }
     }

}

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

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

Удачи.

Ещё вопросы

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