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 . . .
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 . . .
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:
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.,
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
... so I don't understand what the program is doing to make these events happen. How do I figure that out?
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.
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.
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.
So short answer to your question would be - all events used in your example are triggered by WPF rendering system.
A rough guess is that it is calling InvalidateVisual() from within a recurrent timer, which at some point will invoke OnRender().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With