ItemsPanel против Grid против GridSplitter - PullRequest
0 голосов
/ 25 февраля 2010

В настоящее время я пытаюсь создать ControlTemplate для ItemsControl, который использует Grid в качестве своей ItemsPanel, где каждый элемент расположен горизонтально и разделен с помощью GridSplitter.

Основная цель - иметь динамически привязываемый ItemsControl, в котором все элементы располагаются в ряд и размер каждого элемента может быть изменен с помощью разделителя.

Есть две вещи, которые я не могу обернуть вокруг себя: Как GridSplitter должен автоматически заканчиваться между каждым элементом? Как настроить Grid.Column для каждого элемента.

Если это невозможно сделать с помощью простого шаблона управления, что было бы распространенным и хорошим способом реализации чего-то подобного? Нужно ли для этого написать новый ItemsControl?

Мне нужны фактические (Grid) элементы управления Splitter, поэтому для них могут быть собственные шаблоны ControlTemplates. Также я думаю, что было бы очень полезно иметь дополнительные функциональные возможности макета для ячеек (GridLengthUnitType, Stretch, Alignment).

Так что при развертывании своего собственного, я думаю, мне понадобится настраиваемый ItemsControl (который генерирует разделители для каждого элемента) и настраиваемая панель (которая ведет себя как сетка onerow / onecolumn - так что нет необходимости в прикрепленных Grid.Row, Grid Свойства столбца. (Ориентация будет достаточной), которые могут принимать элементы управления Splitter и знают, как с ними обращаться в плане компоновки.

Что вы думаете об этом подходе? Является ли предпочтительным или хорошим способом?

Ответы [ 2 ]

2 голосов
/ 24 марта 2010

Насколько я понимаю, ItemsControl основан на идее, что для каждого элемента он создает только один элемент управления и добавляет его к элементуhost. Создание как GridSplitter, так и элемента-контейнера по умолчанию для каждого элемента противоречит этому принципу.

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

Таким образом, логика изменения размера должна быть реализована на пользовательской панели. Это самый большой недостаток, но IMO того стоит, потому что он спрятан только в одном месте. Вам не нужно делать ничего особенного в вашем ItemsControl / ItemTemplate / ItemContainerStyle, кроме как использовать эту панель в качестве itemshost.

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

0 голосов
/ 19 марта 2010

Вам нужно поместить гридсплиттер в отдельный столбец. Предполагая, что сетка будет иметь только одну строку, нет необходимости устанавливать Grid.Row для любого элемента. Однако, если вы хотите, вы можете установить его в 0 (первая строка).

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

...