Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何避免WPF对我自己的控件进行安排/测量?_Wpf - Fatal编程技术网

如何避免WPF对我自己的控件进行安排/测量?

如何避免WPF对我自己的控件进行安排/测量?,wpf,Wpf,我已经在C#中开发了一个3D引擎,我希望它能够在WPF应用程序中通过可以像其他WPF控件一样使用的类来使用 首次实施 我创建了一个扩展Grid类的面板(我们称之为EnginePanel),以及一组要放入其中的控件,如ScenendoControl、GeometryControl等。。。这些控件继承FrameworkElement WPF类 对于scenendecontrol,我公开了一个Children属性(UIElementCollection)并重写了该逻辑/可视化管理方法,以便它们查看该集

我已经在C#中开发了一个3D引擎,我希望它能够在WPF应用程序中通过可以像其他WPF控件一样使用的类来使用

首次实施 我创建了一个扩展Grid类的面板(我们称之为EnginePanel),以及一组要放入其中的控件,如ScenendoControl、GeometryControl等。。。这些控件继承FrameworkElement WPF类

对于scenendecontrol,我公开了一个Children属性(UIElementCollection)并重写了该逻辑/可视化管理方法,以便它们查看该集合内部

我还重写了ArrangeOverride和MeasureOverride方法,以便在SceneNodeControl的每个子级上调用Arrange/Measure,然后返回一个恒定的零像素大小

这个实现可以工作,并允许我使用ItemsControl、ContentControl和DataTemplates用经典的MVVM模式填充场景图

问题 我的问题是,如果我创建了一个包含数百个SceneNoDeControl的大型场景图,那么应用程序的速度会显著降低

VisualStudioProfiler的快速检查告诉我,ScenendoControl中的度量方法负责80%到90%的CPU使用率(就所花费的时间而言)

好的,没问题。我要做的是删除这些在我看来过于繁重而且毫无用处的计算

解决方案1 我试图简单地取消对ScenendoControl子对象的排列/测量方法的调用

这是行不通的。如前所述,这些方法的实现必须在子级上调用Arrange/Measure

解决方案2 继承FrameworkContentElement。实际上,这个类没有布局算法

但是它没有任何可视化的树管理,这使得它不能用于ItemsControl、ContentControl和DataTemplates

其他解决方案 我没有其他的解决办法。。。这就是为什么我现在在这里

问题是如何避免WPF对我自己的控件进行安排/测量

谢谢

编辑 解决方案3 我找到了解决问题的另一种方法(但它产生了越来越多的问题)

我的控件可以继承DependencyObject类。通过这种方式,应该可以使用来自其他WPF控件的DataContextes,更一般地说,是它们的DependencyProperties

问题1:我不能使用现有的DataTemplate、ItemsControl和ContentControl类,但我可能可以重新实现它们

问题2:我不能告诉DependencyObject是另一个DependencyObject的“父对象”。我发现了一些“反映”这个类并公开隐藏成员的黑客,试图管理InheritanceContext和InheritanceParent。但由于似乎没有人这么做,而且微软显然不想让我们使用它,这真的很难

关于第二个问题,我可能会提出一个新问题。(编辑:是的。)

编辑:集中我的问题 我要写的是这样的东西:

<controls:SceneNodeControl NodeName="Root">
    <ItemsControl ItemsSource="{Binding SceneNodes}">
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type local:SceneNodeViewModel}">
                <controls:SceneNodeControl NodeName="{Binding Name}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</controls:SceneNodeControl>

并且,在运行时,不要对SceneNodeControl执行度量/排列算法,而是构建它们的逻辑/视觉树


这是我的小测试项目。

如果您不想测量和排列从NodeSceneControl开始的逻辑树,并且不想渲染它,只需将其Visibility属性设置为Visibility.Collapsed即可。这样,该节点将被排除在布局处理之外。

我仍然认为您的做法是错误的。。。如果你想使用WPF,那么你必须遵守它的规则。如果没有这两种方法,您的项目将无法呈现。不过还有其他选择。。。那么数据虚拟化呢?阅读MSDN上的页面,看看您还可以做些什么来提高性能。重点是我不需要呈现这些元素,只需要更新即可。我的EnginePanel使用这些元素填充场景图(查看数据的另一种方式),该场景图本身用于计算EnginePanel渲染的最终图像(使用DirectX 9技巧)。最后,WPF中呈现的唯一元素是EnginePanel,而不是SceneNodeControl或GeometryControl。我刚刚意识到,我想要的只是在我的控件上使用绑定,并让WPF(可能不是WPF那样做)用DataTemplates和ItemsControl/ContentControls实例化这些控件。这一点很好!它会停止MeasureOverride和ArrangeOverride的执行。但它不允许我在ScenendoControl中使用ItemsControl和DataTemplate。我将UIElementCollection用作ScenendoControl的子级:是否必须对其设置特殊参数?或者在这些子级上调用一些“隐藏”算法来构造VisualTree和/或LogicalTree?为什么不能使用DataTemplate和ItemsControl。也许我遗漏了什么,但我看不出节点的可见性状态会如何影响其逻辑树。试试看。对于我刚刚发布的示例,“根”节点只调用了一次SceneNodeControl的构造函数。如果我移除Vibility.Collapsed标志,构造函数将被传递5次(一次用于我的根,一次用于我的SceneNodes中的每个ScenenoDeviceWModel)。未生成可视化树。我不知道为什么:pI发布了一个项目,在那里我测试了我们对我的原始问题所说的一切。自由地测试自己。非常感谢。