WPF控制问题 [英] WPF Control issues

查看:100
本文介绍了WPF控制问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临一个问题,即WPF应用程序无法更新进度条,即使wpf窗口上的按钮停止发光,直到我移动窗口,然后一切都很好为止。

I am facing one issue in which WPF application unable to update the progress bar even the button on the wpf window stop glowing untill i move the window then everything is fine.

我每次尝试更新进度条时都会尝试调用InvalidateRect,该进度条实际上会生成WM_PAINT消息,但不能解决问题。这个问题在某些情况下是随机发生的。

I have try to call InvalidateRect everytime i update the progress bar which actually generate the WM_PAINT message but doesn't solve the issue. This issue is random some time happend some time doesn't happend.

我的应用程序在支持增强型视频渲染的情况下使用DirectShow进行视频渲染。如果我用VMR替换增强型视频渲染器,一切正常。

My application is using DirectShow at the backened with Enhanced Video Rendering for video rendering. If i replace the Enhanced Video Renderer with VMR everything works fine.

如果有人可以帮助我,我将不胜感激。

I will appreciate if any one can help me .

感谢
Sohrab。

Thanks Sohrab.

推荐答案

我了解您为什么尝试使用WM_PAINT来解决问题。但是,WM_PAINT确实与WPF渲染完全无关。

I understand why you tried WM_PAINT to fix your problem. However WM_PAINT really has nothing to do with WPF rendering at all.

基本上,这是WPF在Window(或HwndSource,ElementHost等)中进行渲染的方式。首先在屏幕上显示:

Basically, here is how WPF does its rendering when a Window (or HwndSource, ElementHost, ...) is first shown on the screen:


  1. Window对象的可见性设置为可见

  2. 已分配并显示了Win32窗口(hWnd),但其WM_PAINT被忽略了

  3. 分配了Direct3D Surface来覆盖Win32窗口的区域

  4. Dispatcher回调计划在DispatcherPriority.Render

  5. 启动Dispatcher回调时,将测量并排列窗口的可视树

  6. 在每次遍历遍历期间控件生成绘图指令以绘制自身并将其存储在DrawingContext中

  7. 在整理过程结束时,WPF读取DrawingContext数据并使用Direct3D更新屏幕

  1. A Window object has its Visibility set to "Visible"
  2. A Win32 window (hWnd) is allocated and shown, but its WM_PAINT is ignored
  3. A Direct3D Surface is allocated to cover the Win32 window's area
  4. A Dispatcher callback is scheduled at DispatcherPriority.Render
  5. When the Dispatcher callback fires, the window's visual tree is measured and arranged
  6. During the arrange pass every control generates drawing instructions to draw itself and stores these in a DrawingContext
  7. At the end of the arrange pass WPF reads the DrawingContext data and uses Direct3D to update the screen

从那时起,只要进行了影响显示的属性更改,步骤4-7的主要部分以极其有效的增量方式重复进行,仅更新需要更新的内容。

From then on, any time a property change is made that affects the display, relevant portions of steps 4-7 are repeated in an extremely efficient incremental fashion, updating only what needs to be updated.

这里要注意的关键是,任何时候如果要完成渲染工作,则调度Dispatcher回调来完成。这意味着只要以下条件,您的UI就会继续呈现:

The key thing to note here is that any time there is rendering work to be done, a Dispatcher callback is scheduled to do it. This means that your UI will continue to render as long as:


  1. 分派器正在处理其队列,并且

  2. 您不会连续添加或高于渲染优先级的调度程序操作

此外,输入事件的处理会在Input处进行优先级,因此如果您希望将鼠标悬停在按钮上,则至少需要允许Dispatcher向下执行到Input优先级。

In addition, processing of input events happens at Input priority, so you need to at least allow the Dispatcher to execute down to Input priority if you want mouse over to work on buttons.

由于WPF的工作方式,发送WM_PAINT根本不执行任何操作。您要做的就是让分派器有机会处理其队列。通常,这是通过从UI线程调用Dispatcher.Invoke并传递低于您要刷新的事件的优先级来完成的,例如:

Because of the way WPF works, sending WM_PAINT doesn't do anything at all. What you want to do is to give the Dispatcher a chance to process its queue. Generally this is done by calling Dispatcher.Invoke from the UI thread and passing a priority lower than the events you want to flush, for example:

Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, new Action(() => {}));

请注意,该操作什么也不做。但是对Dispatcher.Invoke的调用在执行空操作之前不会返回,并且在执行所有更高优先级的操作之前无法执行空操作。因此,以上代码具有强制渲染同步进行的效果,类似于在Win32中执行SendMessage(WM_PAINT,...)时会发生的情况。

Notice that the action does nothing at all. But the call to Dispatcher.Invoke cannot return until the empty action executes, and the empty action cannot execute until all higher priority actions execute. So the above code has the effect of forcing the rendering to happen synchronously, similar to what would happen when doing SendMessage(WM_PAINT, ...) in Win32.

一种方法诊断问题的原因是将DispatcherTimer设置为定期写入控制台。通过以各种优先级级别运行此计时器,您可以确定阻止Dispatcher队列的原因。如果没有任何级别的运行,则可能是外部原因锁定了UI线程,在这种情况下,中断进程并检查堆栈可能会有所帮助。一个分析工具甚至更好。在每种情况下,请确定进程是在执行代码还是在等待锁定。如果正在执行代码,请弄清楚为什么该代码永不返回,从而使分派器有运行的机会。如果正在等待锁,请找出谁持有该锁。

One way do diagnose the problem is to set a DispatcherTimer to periodically write to the console. By running this timer at various priority levels you can determine what is holding up the Dispatcher queue. If nothing is running at any level it is probably something external locking up the UI thread, in which case breaking the process and checking the stack may help. A profiling tool is even better for this. In each case, determine whether the process is executing code or waiting for a lock. If it is executing code, figure out why that code never returns to give the Dispatcher a chance to run. If it is waiting for a lock, figure out who is holding that lock.

这篇关于WPF控制问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆