backgroundworker中的C#ProgressBar数据绑定
我不是c#方面的专家,但我想做的是在后台工作程序中更新progressbar。我正在使用以下代码:backgroundworker中的C#ProgressBar数据绑定,c#,multithreading,winforms,backgroundworker,C#,Multithreading,Winforms,Backgroundworker,我不是c#方面的专家,但我想做的是在后台工作程序中更新progressbar。我正在使用以下代码: progressBar1.DataBindings.Add("Value", _dm, "Progress", true, DataSourceUpdateMode.OnPropertyChanged); 当在GUI线程上没有后台工作线程的情况下执行时,此操作有效。Progress属性是一个从另一个backgroundworker(我
progressBar1.DataBindings.Add("Value", _dm, "Progress", true,
DataSourceUpdateMode.OnPropertyChanged);
当在GUI线程上没有后台工作线程的情况下执行时,此操作有效。Progress属性是一个从另一个backgroundworker(我无权访问)的进度更新(使用INotifyPropertyChanged)的属性
我怎样才能使它工作起来,从而使用backgroundworker更新它,而不是将它全部放在GUI线程上
我的代码(简化):
GUI元素需要在UI线程中更新。您需要使用Control.Invoke更新控件属性。Mora关于这个问题:数据绑定应该在构造函数中创建,因为您只需要创建一次绑定,而不是每次需要时:
public MainForm()
{
InitializeComponent();
_dm = new DownloadManager();
progressBar1.DataBindings.Add("Value", _dm, "Progress", true, DataSourceUpdateMode.OnPropertyChanged);
}
您的代码无法工作,因为您试图从非UI线程更新UI。您需要将代码包装在Invoke()
call中,例如使用表单上的代理属性:
public partial class MainForm
{
private double _progress;
public double Progress
{
get { return _progress; }
set
{
_progress = value;
// If not in the UI thread -> wrap the update in an Invoke() call:
if (this.InvokeRequired)
{
this.Invoke(new Action(() => progressBar1.Value = (int) _progress), new object[] { });
return;
}
// Else update directly
progressBar1.Value = (int) value;
}
}
private readonly DownloadManager _dm;
public MainForm()
{
InitializeComponent();
_dm = new DownloadManager();
// Bind _db.Progress <-> this.Progress
DataBindings.Add("Progress", _dm, "Progress", true, DataSourceUpdateMode.OnPropertyChanged);
}
public分部类MainForm
{
私人双(u)进程;;
公共双进步
{
获取{return\u progress;}
设置
{
_进步=价值;
//如果不在UI线程->在Invoke()调用中包装更新:
if(this.invokererequired)
{
调用(新操作(()=>progressBar1.Value=(int)u progress),新对象[]{});
返回;
}
//否则直接更新
progressBar1.Value=(int)值;
}
}
私有只读下载管理器_dm;
公共表格(
{
初始化组件();
_dm=新的下载管理器();
//Bind _db.Progress这个,Progress
DataBindings.Add(“Progress”,dm,“Progress”,true,DataSourceUpdateMode.OnPropertyChanged);
}
也不起作用。我忘了把它添加到我的简化代码中
public partial class MainForm
{
private double _progress;
public double Progress
{
get { return _progress; }
set
{
_progress = value;
// If not in the UI thread -> wrap the update in an Invoke() call:
if (this.InvokeRequired)
{
this.Invoke(new Action(() => progressBar1.Value = (int) _progress), new object[] { });
return;
}
// Else update directly
progressBar1.Value = (int) value;
}
}
private readonly DownloadManager _dm;
public MainForm()
{
InitializeComponent();
_dm = new DownloadManager();
// Bind _db.Progress <-> this.Progress
DataBindings.Add("Progress", _dm, "Progress", true, DataSourceUpdateMode.OnPropertyChanged);
}