WPF如何确定应该重绘某些内容?我如何找到答案?

时间:2015-05-18 11:08:10

标签: c# wpf opengl

嗯,WPFish基金会的内容非常深入,但请看:

简短:如何实现我自己的RenderThread。

我正在解决一个问题,我需要在WPF应用程序中显示10Bit。对于这个和其他原因,它必须是OpenGL(它能够做10Bit)。绑定和WPF控件是众所周知的,它们的特性深受我们的喜爱。因此对于少数控件,我希望使用它们,甚至可以在我的OpenGL环境中绘制它们。

有趣的是,我使用自己的PresentationSource将WPF的某些部分作为独立的Object树工作。布局工作正常,但由于缺少部件(焦点),事件当前失败。可能事件永远不会起作用,因为不可能从某些内部类派生,如CompositionTarget ......: - /

BUT:

所以我可以在我的OpenGL上下文中做自己的绘图(只是一个按钮和边框的副本),但是我无法理解我的想法来检查WPF Visual-Tree,抓住所有{ {1}}并在OpenGL中重做绘画。

我得到的是DrawingGroupsDrawingGroupsEllipseGeometry的树 - 所以可绘制的图元。

RectangleGeometry

这个想法的问题是:我如何确定/我的可视树是否已经改变。我的意思不是整个而是依赖属性。解释:有一个WPF覆盖 DrawingGroup drawing = VisualTreeHelper.GetDrawing((Visual) firstChild); 但是根据我的观察,它不经常调用。我想要观察的是:当动画发生时,它会动画显示例如Width或Opacity或Brushes,它们是Visual-Tree的一部分。我需要重新绘制我的OpenGL上下文。 WPF如何确定以及如何观察?

1 个答案:

答案 0 :(得分:2)

我认为LayoutUpdated应该能满足您的需求。

考虑以下代码示例: 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>

代码背后:

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");
    }
}