需要了解这个WPF程序中的事件触发。

时间:2022-08-10 00:02:23

I'm trying to learn SharpDX by using an example program (http://sharpdxwpf.codeplex.com/SourceControl/latest#SharpDX.WPF.sln) ... it creates a quadrant of 4 shaded triangles using 4 different approaches and it just runs by itself redrawing the graphics. It runscontinuously and seems to be event-driven because I continuously hit breakpoints in event handlers (see below) but I don't understand what triggers these events. In the XAML it has . . .

我试图通过使用一个示例程序(http://sharpdxwpf.codeplex.com/SourceControl/latest#SharpDX.WPF.sln)来学习SharpDX……它使用4种不同的方法创建一个由4个阴影三角形组成的象限,它自己重新绘制图形。它是连续运行的,并且似乎是事件驱动的,因为我在事件处理程序中不断地遇到断点(见下面),但是我不知道是什么触发了这些事件。在XAML中……

  xmlns:dxc="clr-namespace:SharpDX.WPF;assembly=SharpDX.WPF"

. . .

<dxc:DXElement Grid.Column="0" Grid.Row="0" x:Name="dxview10"/>
<Image Grid.Column="1" Grid.Row="0" x:Name="img"/>       
<dxc:DXElement Grid.Column="0" Grid.Row="1" x:Name="dxview11"/>
<dxc:DXElement Grid.Column="1" Grid.Row="1" x:Name="dxview2d"/>

. . . Where DXElement's declaration and constructor look like this . . .

。DXElement的声明和构造函数如下所示…

public class DXElement : FrameworkElement, INotifyPropertyChanged

public DXElement()      
{         
    base.SnapsToDevicePixels = true;         
    m_renderTimer = new Stopwatch();         
    m_surface = new DXImageSource();          
    m_surface.IsFrontBufferAvailableChanged += delegate         
    {                
        UpdateReallyLoopRendering();
        if (!m_isReallyLoopRendering && m_surface.IsFrontBufferAvailable)
            Render();
        };
        IsVisibleChanged += delegate { UpdateReallyLoopRendering(); };
    }

The rest of DXElement is just brief event handlers. Here's one example:

DXElement的其余部分只是简短的事件处理程序。这里有一个例子:

protected override void OnRender(DrawingContext dc)
{
    dc.DrawImage(Surface, new Rect(RenderSize));
}

Notice the "override". I'm assuming that one of the parent classes of DXElement ( FrameworkElement or INotifyPropertyChanged ) are already listening for these events. But what's triggering these events? (e.g., OnRender(), OnLoopRendering(), etc) They seem to be the engine that runs the program. How can I track what causes events like this to fire in a WPF program? If I set a breakpoint at them I see them getting hit, but they're called from the framwework, e.g.,

注意到“覆盖”。我假设DXElement (FrameworkElement或INotifyPropertyChanged)的父类之一已经在监听这些事件。但是是什么触发了这些事件呢?(例如,OnRender()、OnLoopRendering()等)它们似乎是运行程序的引擎。如何跟踪WPF程序中引发此类事件的原因?如果我给它们设置断点,我看到它们被击中,但它们是从framwework调用的,例如,

SharpDX.WPF.dll!SharpDX.WPF.DXElement.OnRender(System.Windows.Media.DrawingContext dc) Line 153 C# PresentationCore.dll!System.Windows.UIElement.Arrange(System.Windows.Rect finalRect) Unknown PresentationFramework.dll!System.Windows.Controls.Grid.ArrangeOverride(System.Windows.Size arrangeSize) Unknown PresentationFramework.dll!System.Windows.FrameworkElement.ArrangeCore(System.Windows.Rect finalRect) Unknown PresentationCore.dll!System.Windows.UIElement.Arrange(System.Windows.Rect finalRect) Unknown PresentationFramework.dll!MS.Internal.Helper.ArrangeElementWithSingleChild(System.Windows.UIElement element, System.Windows.Size arrangeSize) Unknown PresentationFramework.dll!System.Windows.Controls.ContentPresenter.ArrangeOverride(System.Windows.Size arrangeSize) Unknown

SharpDX.WPF.dll ! SharpDX.WPF.DXElement.OnRender(System.Windows.Media。行153 c# PresentationCore.dll!System.Windows. windows . uielement. arrangement (System.Windows. System.Windows)矩形finalRect)未知PresentationFramework.dll ! System.Windows.Controls.Grid.ArrangeOverride(System.Windows。大小arrangeSize)未知PresentationFramework.dll ! System.Windows.FrameworkElement.ArrangeCore(System.Windows。矩形finalRect)未知PresentationCore.dll ! System.Windows.UIElement.Arrange(System.Windows。矩形finalRect)未知PresentationFramework.dll ! MS.Internal.Helper.ArrangeElementWithSingleChild(System.Windows。UIElement元素,System.Windows。大小arrangeSize)未知PresentationFramework.dll ! System.Windows.Controls.ContentPresenter.ArrangeOverride(System.Windows。大小arrangeSize)未知

... so I don't understand what the program is doing to make these events happen. How do I figure that out?

…所以我不明白这个程序是怎么让这些事情发生的。我怎么算出来的?

2 个解决方案

#1


5  

They use per-frame rendering using global CompositionTarget.Rendering event. It is get called once per frame, for all subscribers. You can read more details about it here: https://msdn.microsoft.com/en-us/library/ms748838%28v=vs.100%29.aspx.

他们使用全局合成目标使用每帧渲染。呈现的事件。对于所有订阅者,每个帧调用一次。您可以在这里阅读更多关于它的详细信息:https://msdn.microsoft.com/en-us/library/ms748838%28v=vs.100%29.aspx。

At DXElement source code you see Renderer dependency property. In property changed handler for this property you will see how they subscribe to mentioned CompositionTarget.Rendering event if some conditions match (control is visible, not in design mode and so on). They also start Stopwatch to measure how much time has passed since the beginning, then render the frame.

在DXElement源代码中,您可以看到Renderer dependency属性。在这个属性的属性更改处理程序中,您将看到他们如何订阅提到的CompositionTarget。如果某些条件匹配,则呈现事件(控件是可见的,而不是设计模式等)。他们也开始秒表测量从开始到结束的时间,然后渲染框架。

As for OnRender handler you mentioned. This one is called during layout pass (when parent controls decide how to lay out their children) under some conditions. It is called once when DXElement is first rendered, then it is called when you for example resize DXElement, or call InvalidateVisual on it. But it is not called when those triangles change color in your example - this is done using CompositionTarget.Rendering event.

至于你提到的OnRender处理程序。在某些条件下,在布局传递期间(当父控件决定如何布局其子元素时)调用此方法。在第一次呈现DXElement时调用它一次,然后在例如调整DXElement的大小时调用它,或者在DXElement上调用InvalidateVisual。但是,当这些三角形在你的示例中改变颜色时,它就不会被调用——这是通过使用CompositionTarget完成的。呈现的事件。

So short answer to your question would be - all events used in your example are triggered by WPF rendering system.

您的问题的简短回答是-在您的示例中使用的所有事件都是由WPF呈现系统触发的。

#2


1  

A rough guess is that it is calling InvalidateVisual() from within a recurrent timer, which at some point will invoke OnRender().

一个粗略的猜测是,它从一个重复的计时器中调用InvalidateVisual(),这个计时器在某些时候将调用OnRender()。

#1


5  

They use per-frame rendering using global CompositionTarget.Rendering event. It is get called once per frame, for all subscribers. You can read more details about it here: https://msdn.microsoft.com/en-us/library/ms748838%28v=vs.100%29.aspx.

他们使用全局合成目标使用每帧渲染。呈现的事件。对于所有订阅者,每个帧调用一次。您可以在这里阅读更多关于它的详细信息:https://msdn.microsoft.com/en-us/library/ms748838%28v=vs.100%29.aspx。

At DXElement source code you see Renderer dependency property. In property changed handler for this property you will see how they subscribe to mentioned CompositionTarget.Rendering event if some conditions match (control is visible, not in design mode and so on). They also start Stopwatch to measure how much time has passed since the beginning, then render the frame.

在DXElement源代码中,您可以看到Renderer dependency属性。在这个属性的属性更改处理程序中,您将看到他们如何订阅提到的CompositionTarget。如果某些条件匹配,则呈现事件(控件是可见的,而不是设计模式等)。他们也开始秒表测量从开始到结束的时间,然后渲染框架。

As for OnRender handler you mentioned. This one is called during layout pass (when parent controls decide how to lay out their children) under some conditions. It is called once when DXElement is first rendered, then it is called when you for example resize DXElement, or call InvalidateVisual on it. But it is not called when those triangles change color in your example - this is done using CompositionTarget.Rendering event.

至于你提到的OnRender处理程序。在某些条件下,在布局传递期间(当父控件决定如何布局其子元素时)调用此方法。在第一次呈现DXElement时调用它一次,然后在例如调整DXElement的大小时调用它,或者在DXElement上调用InvalidateVisual。但是,当这些三角形在你的示例中改变颜色时,它就不会被调用——这是通过使用CompositionTarget完成的。呈现的事件。

So short answer to your question would be - all events used in your example are triggered by WPF rendering system.

您的问题的简短回答是-在您的示例中使用的所有事件都是由WPF呈现系统触发的。

#2


1  

A rough guess is that it is calling InvalidateVisual() from within a recurrent timer, which at some point will invoke OnRender().

一个粗略的猜测是,它从一个重复的计时器中调用InvalidateVisual(),这个计时器在某些时候将调用OnRender()。