WPF рисование производительности с большими числами элементов

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

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

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

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

Править: Это связано с моим другим вопросом.

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


    
        
        
    
    
        
        
    

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

5
задан Community 23 May 2017 в 12:30
поделиться

3 ответа

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

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

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

Ссылка на пользовательский образец отрисовки WPF

9
ответ дан 13 December 2019 в 22:08
поделиться

Подчеркивание традиционно допускалось в идентификаторах на большинстве языков программирования и, как правило, было единственным разрешенным «специальным» символом.
Но многие веб-логин по-прежнему не принимают какой-ЛИБО специальный символ и ограничены нижние/верхние регистры символов и цифр...
И другие прекрасно относятся к действительно особым; -)

-121--1604008-

Самый короткий путь к ответу - это, как это часто бывает, Ryan Bates ' Railscasts . У него есть эпизод на с использованием jQuery with Rails . Хотя он специально не покрывает это, достаточно элегантное решение может быть создано из основ, которые он показывает.

В моем случае ссылка редактирования будет переопределена для отправки запроса ajax на сервер, который возвращает javascript для построения частичного кода с кодом редактирования формы. Полегче, как только знаешь как!

-121--4782456-

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

1
ответ дан 13 December 2019 в 22:08
поделиться

Сначала позвольте мне сказать, что ответ Джона верен. Это одна из самых волосатых частей спецификации, так что хорошо на Джоне для погружения в голову первым.

Во-вторых, позвольте мне сказать, что эта строка:

Существует неявное преобразование из группы методов в совместимый тип делегата

(добавлено ударение) глубоко вводит в заблуждение и вызывает сожаление. Я поговорю с Мэдсом о том, чтобы удалить слово «совместимый.»

Причина, по которой это вводит в заблуждение и вызывает сожаление, заключается в том, что это выглядит как ссылка на раздел 15.2 «Совместимость делегата». В разделе 15.2 описывается взаимосвязь совместимости между методами и типами делегатов , но это вопрос конвертируемости групп методов и типов делегатов , который отличается.

Теперь, когда мы убрали это с пути, мы можем пройти через раздел 6.6 спецификации и посмотреть, что мы получим.

Для разрешения перегрузки необходимо сначала определить, какие перегрузки являются применимыми кандидатами . Кандидат применим, если все аргументы неявно преобразуются в формальные типы параметров. Рассмотрим эту упрощенную версию программы:

class Program
{
    delegate void D1();
    delegate string D2();
    static string X() { return null; }
    static void Y(D1 d1) {}
    static void Y(D2 d2) {}
    static void Main()
    {
        Y(X);
    }
}

Давайте пройдемся по ней поочередно.

Существует неявное преобразование из группы методов в совместимый тип делегата.

Я уже обсуждал, как слово «совместимый» прискорбно здесь. Двигаюсь дальше. Мы задаемся вопросом при выполнении разрешения перегрузки на Y (X), преобразуется ли группа методов X в D1? Он преобразуется в D2?

С учетом типа делегата D и выражение E, которое классифицируется как группа методов, неявное преобразование существует от E до D, если E содержит по крайней мере один метод, который применим [...] к список аргументов, созданный с помощью типы параметров и модификаторы D, как описано ниже.

Пока так хорошо. X может содержать метод, применимый к спискам аргументов D1 или D2.

Приложение времени компиляции преобразования из группы методов E в тип делегата D описано ниже.

Эта строка действительно не говорит ничего интересного.

Следует отметить, что наличие неявного преобразования из E в D не гарантирует, что приложение времени компиляции преобразования будет успешным без ошибок.

Эта линия завораживает. Это означает, что существуют неявные преобразования, которые могут быть превращены в ошибки! Это странное правило C #. Ниже приведен пример:

void Q(Expression<Func<string>> f){}
string M(int x) { ... }
...
int y = 123;
Q(()=>M(y++));

Операция приращения недопустима в дереве выражений. Однако лямбда по-прежнему может преобразовываться в тип дерева выражения, даже если преобразование когда-либо используется, это ошибка! Принцип здесь состоит в том, что мы можем захотеть изменить правила того, что может пойти в дереве выражений позже; изменение этих правил не должно изменять системные правила типа . Мы хотим заставить вас сделать ваши программы однозначными сейчас ,так что когда мы меняем правила для деревьев выражений в будущем, чтобы сделать их лучше, мы не вводим разрывные изменения в разрешении перегрузки .

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

Переход:

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

OK. Таким образом, мы перегружаем разрешение на X по отношению к D1. Формальный список параметров D1 пуст, поэтому мы перегружаем разрешение на X () и джой, мы находим метод «string X ()», который работает. Аналогично, список формальных параметров D2 пуст. Опять же, мы находим, что «string X ()» это метод, который также работает здесь.

Здесь принцип заключается в том, что определение конвертируемости группы методов требует выбора метода из группы методов с использованием резолюции перегрузки, и разрешение перегрузки не учитывает возвращаемые типы .

Если алгоритм [...] выдает ошибку, то возникает ошибка времени компиляции. В противном случае алгоритм создает единственный наилучший способ М, имеющий такое же количество параметров, как D, и преобразование считается существующим.

В группе методов X имеется только один метод, поэтому он должен быть лучшим. Мы успешно доказали, что преобразование существует от X к D1 и от X к D2.

Эта строка актуальна?

Выбранный метод M должен быть совместим с типом делегата D, иначе возникает ошибка времени компиляции.

На самом деле, нет, не в этой программе. Мы никогда не доходим до активации этой линии. Потому что, помните, то, что мы здесь делаем, это пытаемся сделать разрешение перегрузки на Y (X). У нас есть два кандидата Y (D1) и Y (D2). Применимы оба варианта. Что лучше ? Нигде в описании не описывается оптимальность между этими двумя возможными преобразованиями .

Теперь, конечно, можно утверждать, что действительное преобразование лучше, чем преобразование, которое приводит к ошибке. Тогда фактически будет сказано, что разрешение перегрузки DOS рассматривает типы возврата, чего мы хотим избежать. Тогда вопрос в том, какой принцип лучше: (1) сохранять инвариант того, что разрешение перегрузки не рассматривает возвращаемые типы, или (2) пытаться выбрать преобразование, которое, как мы знаем, будет работать над тем, которое мы знаем, не будет?

С помощью lambdas мы рассматриваем возвращаемый тип в этих видах преобразований, в разделе 7,4,3,3:

E является анонимной функцией, T1 и T2 являются типами делегатов или деревом выражений типы с идентичными списками параметров, для E существует выведенный тип возврата X в контексте этого списка параметров, и одно из следующих положений:

  • T1 имеет возвращаемый тип Y1, а T2 имеет возвращаемый тип Y2, и преобразование от X до Y1 лучше, чем преобразование из X в Y2

  • T1 имеет возвращаемый тип Y, и T2 является недействительным возвращаемым

К сожалению, преобразования групп методов и преобразования лямбда являются противоречивыми в этом отношении. Тем не менее, я могу жить с этим.

В любом случае, у нас нет правила «betterness», чтобы определить, какое преобразование лучше, X в D1 или X в D2. Поэтому мы приводим ошибку неоднозначности в разрешении Y (X).

-121--732944-

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

Вы должны определить __ версии __ так:

__version__ = '1.4.4'

И тогда вы можете подтвердить, что setup.py знает о только что указанной версии:

% ./setup.py --version
1.4.4
-121--3470705-

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

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

0
ответ дан 13 December 2019 в 22:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: