【问题标题】:WPF update status bar text from backgroundworkerWPF 从后台工作人员更新状态栏文本
【发布时间】:2019-08-09 03:00:45
【问题描述】:

我想在后台进程运行时用字符串更新窗口上有一个状态栏。

具体来说,用户按下一个按钮,就会从文件中读取数据。在读取文件时,会进行后端数据库调用以填充数据对象。这是针对文件中的所有行完成的。这可能需要一点时间。 这一切都在后台工作人员中完成。

我想做的是为用户提供某种正在发生的感觉。我想向用户展示刚刚在状态行上读入的对象的名称。我看到 BackgroundWorker 提供了一个整数更新值,但是我如何做一个字符串以便我可以显示它?

【问题讨论】:

  • 你有代码示例吗?是 WPF 还是 WinForms?
  • 它是 WPF。不,我没有代码示例,因为我知道 ReportProgress / ProgressPercentage 不足以满足我的需要。d
  • 您是否熟悉制作实现INotifyPropertyChanged 的可观察类?

标签: c# wpf


【解决方案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}/>

要更新,只需从 BackgroundWorker 设置 MyStatus.Status 的值。

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 中的工作原理和如何使用它更轻松地更新状态标签等内容。在前端需要更多的工作,但在后端节省了很多时间。

祝你好运。

【讨论】:

    猜你喜欢
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多