【问题标题】:How to know when a control (or window) has been rendered (drawn) in WPF?如何知道何时在 WPF 中呈现(绘制)了控件(或窗口)?
【发布时间】:2012-04-26 09:12:48
【问题描述】:

我需要将 Window 的内容存储到图像中,保存并关闭窗口。如果我在 Loaded 事件上关闭窗口,则图像包含的窗口中的某些项目绘制正常,其他一些仅绘制一半或扭曲,而其他则不在图像上。

如果我设置一个计时器并在一段时间后关闭窗口(250 毫秒到 1 秒之间,具体取决于窗口的复杂性),图像都可以。

看起来窗口需要一些时间才能完全呈现自己。有没有办法知道何时完成渲染以避免使用 Timer 并在我们知道它已完成渲染时关闭窗口?

谢谢。

【问题讨论】:

  • 如何捕捉窗口的图像?
  • 使用 RenderTargetBitmap 类。

标签: c# wpf drawing rendering


【解决方案1】:

我认为您正在寻找ContentRendered 事件

【讨论】:

    【解决方案2】:

    我正在使用的应用程序中遇到了类似的问题, 我通过使用以下代码解决了它,尝试一下,如果有帮助,请告诉我。

     using (new HwndSource(new HwndSourceParameters())
                       {
                           RootVisual =
                               (VisualTreeHelper.GetParent(objToBeRendered) == null
                                    ? objToBeRendered
                                    : null)
                       })
            {
                // Flush the dispatcher queue
                objToBeRendered.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() => { }));
    
                var renderBitmap = new RenderTargetBitmap(requiredWidth, requiredHeight,
                                                          96d*requiredWidth/actualWidth, 96d*requiredHeight/actualHeight,
                                                          PixelFormats.Default);
    
                renderBitmap.Render(objToBeRendered);
                renderBitmap.Freeze();                
    
                return renderBitmap;
            }
    

    【讨论】:

    • Uf.看起来每个人都有自己的问题解决方案,而且没有两个看起来相同。我来看看,但你为什么要实例化一个没有在任何地方使用的 HwndSource?
    • 它强制父窗口等待子窗口被渲染。这对我很有效......!!!
    • 我会尝试,无论如何 ContentRendered 事件对我来说看起来是最简单的方法。
    • 好的,如果你能实现,请在此处发布,我们会知道一个可能比我实施的更好的解决方案。
    【解决方案3】:

    我使用了 SizeChanged 上的方法。

    public partial class MyUserControl: UserControl
    {
    
        public MyUserControl()
        {
            InitializeComponent();
            SizeChanged += UserControl_DoOnce; //register
        }
    
        private void UserControl_DoOnce(object sender, SizeChangedEventArgs e)
        {
            if (ActualHeight > 0)//Once the object has size, it has been rendered.
            {
                  SizeChanged -= UserControl_DoOnce; //Unregister so only done once
            }
        }
    }
    

    这是我发现在控件中可靠地工作而无需引用 Window 的唯一方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-18
      • 1970-01-01
      • 1970-01-01
      • 2016-07-20
      • 2015-05-27
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多