如何在 WPF 上将 Dispatcher 或 BackroundWorker 与自定义 StatusBar 控件一起使用

发布于 2024-12-22 23:50:19 字数 626 浏览 1 评论 0原文

在我的应用程序中,我实现了一个自定义状态栏控件。它有进度条、状态文本框等。其他模块可以使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

总以为 2024-12-29 23:50:19

您想要在另一个线程上运行 SomeMethod(),然后回调 Dispatcher 来更新进度。实际上,如果自定义进度条连接到某个 UI 元素,那么实现应该处理对 UI 线程的回调。

您可能想要类似的东西:

public IconManagerModel(IStatusBar statusBar)
{
    StatusBar = statusBar;

    var thread = new Thread(new ThreadStart(SomeMethod));
    thread.Start();
}

SomeMethod() 现在将在不同的线程上运行,因此如果您更新 UI 线程上的进度,那么您应该会看到您想要的结果。

You want to run SomeMethod() on another thread, then call back onto the Dispatcher 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:

public IconManagerModel(IStatusBar statusBar)
{
    StatusBar = statusBar;

    var thread = new Thread(new ThreadStart(SomeMethod));
    thread.Start();
}

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.

べ繥欢鉨o。 2024-12-29 23:50:19

要添加 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文