2010-01-12 2 views
4

Я пытаюсь создать пользовательский элемент управления в WPF для отображения дерева игр для game of go (см. here для того, как он выглядит). Я больше или меньше работал над созданием узлов, но одна из проблем, которые я обнаружил, заключается в том, что она начинает заметно замедляться для рендеринга/навигации (она находится в средстве просмотра прокрутки), когда количество узлов становится больше, чем примерно 30. Поскольку средняя игра в go состоит из примерно 200 ходов (не говоря уже о других ветвях, которые игрок может развить), это будет довольно большой проблемой в любой реалистичной игре.Производительность чертежа WPF с большим количеством элементов

В настоящее время я использую отдельные пользовательские элементы управления для игровых узлов (каждый из которых является эллипсом с эффектом теневого растрового изображения на нем и некоторой текстовой аннотацией) и простыми строками для дуг в дереве, все из которых расположены абсолютно в холсте.

Алгоритм компоновки не является такой проблемой, поскольку это нужно выполнять только при создании новой ветви (иначе узел может быть добавлен непосредственно под его родителем, поэтому другие узлы не должны быть перемещены). Основная проблема заключается в том, что любое манипулирование этим холстом и его элементами происходит очень медленно, по-видимому, только из-за количества детей, которое у него есть. Очевидно, что он становится медленнее по мере увеличения ширины и сложности дерева, поскольку есть больше дуг, а также узлов.

Мой вопрос: Каков правильный способ рисования такой крупной/сложной структуры, как это происходит так, что она не проявляется слишком медленно по мере ее роста?

Редактировать: Это связано с my other question.

Edit: Вот разметка для пользовательских элементов управления, которые я использую для узлов:

<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> 

Они добавляются динамически на холст, чтобы нарисовать дерево.

ответ

8

Управление рендерингом на самом деле довольно дорого. Если вы делаете собственный чертеж (рисовать элементы самостоятельно, а не размещать элементы управления) в клиентской области, вы резко увеличите свою производительность.

Это был мой опыт снова и снова при выполнении такого рода работ. Если вам нужно более дюжины элементов управления, пойдите для владельца, нарисованного.

Кстати, не позволяйте производителю рисовать вас. Это не слишком сложно, чем динамическое управление элементами.

Ссылка на custom WPF drawing sample

+0

По индивидуальному рисунку вы имеете в виду размещение соответствующих фигур (эллипсов и т. Д.) В коде кода GameTree, а не в отдельном пользовательском элементе управления или выполнении чего-то более низкого уровня? Не могли бы вы дать мне быстрый пример или ссылку, объясняющую это? Благодаря! –

+0

++ Да. Нарисуйте его самостоятельно, и если есть мерцание, нарисуйте растровое изображение и переместите его в окно. –

+1

Вот ссылка, которая объясняет, как можно рисовать основные формы WPF: http://msdn.microsoft.com/en-us/library/ms747393.aspx В вашем случае вам нужно совместить рисование теневых кругов, затем линии , затем заполненные круги с границей, текст. Сначала это будет казаться сложным, но поиграть с ним. Вы узнаете, как весело рисовать с помощью .Net может быть! –

1

Я 4-D Перейти игрок сам :) Вы можете создать битовую карту доски, и просто перерисовать часть, которая изменилась.

+1

Проблема в том, что я хочу, чтобы камни и узлы в игре дерево, чтобы быть интерактивным, поэтому автоматическое тестирование ударов и т. д., предоставляемое пользовательскими элементами управления, полезно. –

+1

И да, Go очень интересно, когда вы распространяете его на разные геометрии платы! Я написал игровой движок, позволяющий использовать доски с произвольной геометрией и произвольным количеством игроков. Как вы играете в 4D? Визуальная проекция на 3D/2D пространство? –

+0

Вы можете нарисовать 4D-пространство в 2D так же, как вы можете нарисовать 3D-пространство в 2D. Попробуйте однажды нарисовать кубик 4D - просто используйте то же обобщение, которое вы делаете для рисования 3D-куба из 2D-куба (квадрат). –

0

Я знаю, что это может не ответить на вопрос, но я думаю, что стоит отметить.

WPF4 появится в ближайшем будущем, и он будет поддерживать кеширование графики элемента, делая во многих случаях перерисовывание ненужным. Добавьте пару атрибутов на элементы, которые вы хотите использовать в этом, и вам хорошо идти. Если вы в конечном итоге используете это, старайтесь избегать ненужных анимаций. Нет смысла кэшировать вещи, если каждый элемент на экране требует перерисовки на каждом кадре. Ролловер анимации будет хорошо.

+0

Полезно знать, спасибо. Приходит ли это с .NET 4? –

+0

Да. Я не могу себе представить, что дата выпуска тоже будет длинной. Не ходите мимо меня. = р – YotaXP

0

Я не знаю, если вам понравится мое предложение, потому что это будет выглядеть некрасиво, но вы можете попробовать, чтобы отключить сглаживание по:

Установить RenderOptions.EdgeMode для текущего окна в «Не выбрано» (без сглаживания)

Вы должны получить лучшую производительность, но какой-то грубый рисунок.

Удачи вам! Eric

Смежные вопросы