How does WPF determine when something needs to be redrawn? How to find out?

Well, this is pretty deep in WPFish foundations, but see:

In short: how to implement your own RenderThread.

I am working on an issue where I need to display 10Bit inside a WPF application. For this and for other reasons, it must be OpenGL (which is good at doing 10Bit). WPF bindings and controls are well known and are loved by us. So for a few controls, I hope to use them and maybe even draw them in my OpenGL context.

Interestingly, I have some parts of WPF that work as an independent object tree using my own PresentationSource

. The layout works, however, events are currently not working due to missing parts (Focus). Events probably never work because it is impossible to get from some inner classes like CompositionTarget

...: - /

BUT:

So, I can make my own drawing in my OpenGL context (just a copula with buttons and borders), but I can't get Idea not to think about the WPF visual tree, grab everything DrawingGroups

and redo the painting in OpenGL.

What I get is a tree DrawingGroups

, EllipseGeometry

and RectangleGeometry

- such primitives.

    DrawingGroup drawing = VisualTreeHelper.GetDrawing((Visual) firstChild);

      

Problem with this idea: How do I detect if / my visual tree has changed. And I don't mean everything, but the dependency property. Explain that there is a WPF override protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)

, but from my observation it is not called often enough. I want to observe: When animation happens, it animates like Width or Opacity or Brushes that are part of the visual tree. Then I need to redraw my OpenGL context. How does WPF determine and how do I observe it?

+3


source to share


1 answer


I think LayoutUpdated should give you what you need.

Consider this example code: XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Width="525" Loaded="MainWindow_OnLoaded">
    <StackPanel>
        <Canvas x:Name="TargetCanvas"  Height="300">
            <Rectangle x:Name="Subject" Canvas.Top="50" Canvas.Left="50" Fill="Maroon" Height="25" Width="25"/>
        </Canvas>
        <Button Content="Move">
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard Target="{Binding ElementName=Subject}" TargetProperty="(Canvas.Left)" AutoReverse="True">
                            <DoubleAnimation To="200" Duration="00:00:02"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>
    </StackPanel>
</Window>

      



And the code behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
    {
        TargetCanvas.LayoutUpdated += TargetCanvas_LayoutUpdated;
    }

    void TargetCanvas_LayoutUpdated(object sender, EventArgs e)
    {
        Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + ": Layout updated\n");
    }
}

      

+2


source







All Articles