我正在尝试从不同的线程更新UI元素,但我显然遗漏了有关新WPF调用的内容。
在3.5 winforms中,当通过不同的线程更新我的UI时,我做了类似以下的事情:
public string SummaryTitle
{
get
{
if (IsHandleCreated && InvokeRequired)
{
IAsyncResult result = BeginInvoke(new Func<object, object[], object>(GetType().GetProperty("SummaryTitle").GetValue), this, null);
return EndInvoke(result).ToString();
}
return myTextBox.Text.Trim();
}
set
{
if (IsHandleCreated && InvokeRequired)
{
BeginInvoke(new Action<object, object, object[]>(GetType().GetProperty("SummaryTitle").SetValue), this, value, null);
}
else
{
myTextBox.Text = value;
}
}
}
现在使用4.0 WPF我试图模拟上面的内容,但是使用新的Dispatcher(可能除了调度程序之外还有其他/更好的方法吗?)。这是我现在正在玩的原型代码(我知道还有非线程相关的问题,请暂时忽略它)并且它无法正常工作:
public string SomeText
{
get {
if(!myTextBox.Dispatcher.CheckAccess())
{
object o = myTextBox.Dispatcher.Invoke(new Func<object, object[], object>(GetType().GetProperty("SomeText").GetValue), this, null);
return o != null ? Convert.String(o) : "";
}
return myTextBox.Text.Trim();
}
set
{
if (!myTextBox.Dispatcher.CheckAccess())
{
myTextBox.Dispatcher.Invoke(new Action<object, object, object[]>(GetType().GetProperty("SomeText").SetValue),this, value, null);
return;
}
myTextBox.Text = value;
}
}
有关如何使WPF访问器功能类似于旧的3.5 winforms方法的任何帮助将不胜感激。
答案 0 :(得分:1)
我仍然是WPF的新手,但每当我使用调度程序时,我都会指定运行操作的优先级。这确定了动作实际运行的时间
myControl.Dispatcher.BeginInvoke(DispatcherPriority.Render,
new Action(delegate()
{
// Code to execute goes here
}
));
可以找到PriorityLevels列表here
看起来您正在尝试更新进度条...如果您的条形图绑定了某些内容(例如0到100之间的数字),您可以将调度程序调用添加到长时间运行的进程中并且它会更新号码。 DataBinding应该处理其余的事情。
答案 1 :(得分:0)
我知道您有兴趣让Dispatcher正常工作,但对于类似的事情,您是否考虑过使用BackgroundWorker?虽然对优先级等有一点限制,但它确实简化了在更新UI时在后台线程上运行计算。
这是SO thread,我帮助某人使用BackgroundWorker。
当然,如果您正在使用其他线程模型,这可能不适合您 - YMMV - 但如果您只是想在更新ProgressBar时在后台进行一些工作,请查看。