5

我正在尝试在 WPF 中创建一个自定义控件来显示围棋游戏的游戏树(请参阅此处了解它的外观)。我或多或少地让它在布置节点时工作,但我发现的一个问题是,当节点的数量大于大约30. 由于围棋平均由大约 200 步棋组成(更不用说玩家可能分叉到的其他分支),这在任何现实游戏中都将是一个相当大的问题。

目前,我正在为游戏节点(每个都是一个带有阴影位图效果和一些文本注释的椭圆)和树中的弧线使用单独的用户控件,所有这些都绝对定位在画布中。

布局算法不是这样的问题,因为这只需要在创建新分支时执行(否则节点可以直接添加到其父节点下方,因此不需要重新定位其他节点)。主要问题很简单,就是对这个画布及其元素的任何类型的操作都非常缓慢,大概是因为它有很多子元素。随着树的宽度和复杂性的增加,它显然会变慢,因为有更多的弧和节点。

我的问题:绘制这样一个大型/复杂结构的正确方法是什么,这样它在增长时不会渲染得太慢?

编辑:这与我的另一个问题有关

编辑:这是我用于节点的用户控件的标记:

<UserControl x:Class="Go.UI.GameNodeMarker"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Go.UI"
             xmlns:wpftools="clr-namespace:WpfTools.Extensions;assembly=WpfTools"
             x:Name="_This">
    <UserControl.Resources>
        <!-- Some brushes, resources, etc. are omitted -->
        <Style x:Key="StoneStyle" TargetType="{x:Type Ellipse}">
            <Setter Property="StrokeThickness" Value="0"/>
            <Setter Property="BitmapEffect" Value="{StaticResource StoneEffect}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=_This, Path=StoneColour}"  Value="Black">
                    <Setter Property="Fill" Value="{StaticResource BlackStoneBrush}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding ElementName=_This, Path=StoneColour}" Value="White">
                    <Setter Property="Fill" Value="{StaticResource WhiteStoneBrush}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding ElementName=_This, Path=IsEmpty}" Value="True">
                    <Setter Property="Fill" Value="{StaticResource EmptyBrush}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </UserControl.Resources>
    <Grid>
        <Ellipse Style="{StaticResource StoneStyle}"/>
        <TextBlock Text="{Binding ElementName=_This, Path=Text}"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"
                   FontWeight="Medium"/>
    </Grid>
</UserControl>

这些被动态添加到画布中以绘制树。

4

4 回答 4

9

渲染控件实际上非常昂贵。如果您在客户区进行自定义绘图(自己绘制项目而不是放置控件),您将看到您的性能显着提高。

这是我在做这类工作时一次又一次的经历。如果您需要十几个控件,请选择所有者绘制。

顺便说一句,不要让自定义绘图吓倒您。它并不比动态放置控件复杂多少。

链接到自定义 WPF 绘图示例

于 2010-01-12T23:41:21.347 回答
1

我自己是 4-D 围棋选手 :) 您可能想要创建棋盘的位图,然后重绘已更改的部分。

于 2010-01-12T23:52:47.487 回答
1

我不知道您是否会喜欢我的建议,因为它看起来很难看,但您可以尝试通过以下方式关闭抗锯齿:

将当前窗口的 RenderOptions.EdgeMode 设置为“未指定”(无抗锯齿)

你应该得到更好的性能,但某种粗略的绘图。

祝你好运 !埃里克

于 2012-03-08T21:31:12.027 回答
0

我知道这可能无法真正回答这个问题,但我认为值得指出。

WPF4 将在不久的将来推出,它将支持元素图形的缓存,在许多情况下无需重绘。在您想要利用这一点的元素上添加几个属性,您就可以开始了。如果您最终使用它,请尽量避免不必要的动画。如果屏幕上的每个元素都需要在每一帧上重绘,那么缓存是没有意义的。翻转动画会很好。

于 2010-01-13T17:32:15.627 回答