【问题标题】:How to refresh / update the wpf window after adorner has been added / enabled添加/启用装饰器后如何刷新/更新wpf窗口
【发布时间】:2013-07-17 11:49:40
【问题描述】:

我在使用 WPF 的 Adorner 时遇到了一些问题。我的装饰器没问题,但我没有在我想要的时候显示它。

我喜欢做这样的事情:

    public void MyAction()
    {
        // property bound to the adorner VisibiltyProperty
        // I like the happen a refresh now
        // (code is wired correct, if I finish method here, the adorner is drawn)
        this.IsAdornerEnabled = true;

        try
        {
           ... doing some long lasting things I cannot do async cause it depends on a lot of objects owned by main thread...
        }
        finally
        {
            // I like the adorner to be removed from UI now
            this.IsAdornerEnabled = false;
        }
    }

IsAdornerEnabled 属性正确绑定到装饰器并向其发出通知。但是在这段代码中,当方法终止时,装饰器会在瞬间被绘制和移除。

如何在 UI 线程被阻塞之前渲染它?

非常感谢任何帮助。

说明: 我喜欢使用装饰器在我的主选项卡上创建一个不可点击的半透明窗格,上面有“加载模块”之类的文本。当我的 MainThread 使用 magellan 导航,使用 Castle 解决依赖关系,然后创建大量 DevExpress 控件时,我喜欢展示这个窗格。然后我再次删除它。我可以创建装饰器,这没问题。装饰器在我的原型设计项目中工作,我不做任何其他事情。

【问题讨论】:

  • 这是有道理的,因为您的进度不是异步的,使装饰器创建通知等等,但是由于您阻塞了(UI?)线程,所以没有人可以绘制因此没有装饰器被渲染。跨度>
  • 这就是我要问的,如何在阻塞 UI 线程之前强制我的应用程序呈现装饰器?
  • adorder 是否应该像进度条一样工作?
  • 至少目前,它不必表现得像一个进度条。这只是一个超载。但是你新人知道客户接下来有什么想法;-)

标签: c# wpf mvvm refresh adorner


【解决方案1】:

我找到了答案。这可能不是超干净的方式,但它对我有用。

视图模型:

    private void LoadUi()
    {
        try
        {
            this.IsAdornerVisible = true;
            RefreshCallback();

            ... some long going view initialization...
        }
        finally
        {
            this.IsAdornerVisible = false;
        }
}

RefreshCallback 是 action 类型的属性,由 xaml 后面的代码中的方法设置。设置为 RefreshCallback 的方法是这样的:

    private void Refresh()
    {
        this.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle, null);
    }

使用 ContextIdle 在调度程序上调用可以在执行空操作之前完成渲染。 使用 ContextIdle 这很有效。在我尝试 DispatcherPriority 的其他值之前,例如 Render。不工作。现在我很高兴它起作用了,周末可以开始了。

我在这里找到的解决方案: Source of my solution: Update the WPF UI now: how to wait for the rendering to finish

【讨论】:

    【解决方案2】:

    试试这个。

        public void MyAction()
    {
        // property bound to the adorner VisibiltyProperty
        // I like the happen a refresh now
        // (code is wired correct, if I finish method here, the adorner is drawn)
        this.IsAdornerEnabled = true;
    
        try
        {
            this.Dispatcher.Invoke( (Action)(() => 
            { 
                // Do your work here,
    
    
    
    
    
                this.IsAdornerEnabled = false;
            })); 
        }catch {
        }
    
    }
    

    【讨论】:

    • 不幸的是,这段代码应该在不存在 Dispatcher 的 ViewModel 类中......我已经尝试过在 this.AdornedElement 上调用 Dispatcher 并通过回调调用 xaml.cs 中的 Dispatcher。但是绘画还没有完成。
    • 好的,所以你正在使用 MVVM ?
    • 那你真的要使用异步调用了。blog.mycupof.net/2012/08/23/…看看这个
    • 我很想使用异步调用来处理我的长期工作。但是长期的事情会使用 UI 线程拥有的大量对象。我尝试异步使用它,但任务以异常终止,说对象由另一个线程拥有......
    • 但是你违反了 MVVM 规则,对吧?你对 UI 意味着什么你是在视图模型中从 UI 访问元素吗?
    猜你喜欢
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 2015-01-08
    • 2010-11-03
    • 2012-12-20
    相关资源
    最近更新 更多