如何在 WPF 上将 Dispatcher 或 BackroundWorker 与自定义 StatusBar 控件一起使用
在我的应用程序中,我实现了一个自定义状态栏控件。它有进度条、状态文本框等。其他模块可以使用 MEF 获取该类的实例,并使用方法和属性将其数据绑定到他的元素中。问题是状态栏的视图仅在某些操作完成后才会更新。 这是一个代码示例:
[ImportingConstructor]
public IconManagerModel(IStatusBar statusBar)
{
StatusBar = statusBar;
}
public void SomeMethod()
{
for(...)
{
//I tried to use Dispatcher but it didn't help. View updates after method has finished
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal,
delegate()
{
StatusBar.SetProgress(amountComleted,total)
}
);
// ...
}
}
谢谢
In my application I realized a custom statusbar control. It has progressbar, statusTextBox etc. Other modules could get the instance of that class with MEF, and bind their data in his elements with methods and properties. The problem is that the View of my statusbar updates only after some operation has finished.
Here is a code example:
[ImportingConstructor]
public IconManagerModel(IStatusBar statusBar)
{
StatusBar = statusBar;
}
public void SomeMethod()
{
for(...)
{
//I tried to use Dispatcher but it didn't help. View updates after method has finished
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal,
delegate()
{
StatusBar.SetProgress(amountComleted,total)
}
);
// ...
}
}
Thanx
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您想要在另一个线程上运行
SomeMethod()
,然后回调Dispatcher
来更新进度。实际上,如果自定义进度条连接到某个 UI 元素,那么实现应该处理对 UI 线程的回调。您可能想要类似的东西:
SomeMethod()
现在将在不同的线程上运行,因此如果您更新 UI 线程上的进度,那么您应该会看到您想要的结果。You want to run
SomeMethod()
on another thread, then call back onto theDispatcher
to update the progress. Really, if the custom progress bar is hooked up to some UI element, then the implementation should handle the calling back onto the UI thread.You may want something a little like:
SomeMethod()
will now be running on a different thread, so if you update the progress on the UI thread then you should see the results you desire.要添加 slade 的上述答案,如果您希望消息泵进行处理,我还建议使用 DispatcherPriority.Render立即收到消息。使用 Invoke(同步)和 BeginInvoke(异步)。前者将立即强制更新,但会阻止您的处理工作。后者会在消息泵空闲时更新,一般推荐使用。
无论哪种方式,您的后台工作都需要在后台线程上进行,特别是当它很长时,否则它会在持续时间内阻塞您的 UI。
To add to the above answer by slade, I'd also suggest using DispatcherPriority.Render if you want the message pump to process the message immediately. Play around with Invoke (synchronous) and BeginInvoke (asynchronous). The former will force the update immediately, however will block your processing work. The latter will update when the message pump is free and is generally recommended.
Either way your background work needs to be on a background thread, particularly if it is lengthy or it will block your UI for the duration.