Реализация многодоковой оконной системы (например, blend, visual studio) в WPF - PullRequest
9 голосов
/ 11 февраля 2010

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

Существует только одно исключение: в режиме наложения при перетаскивании на окно панели инструментов, которое уже является верхним уровнем (оторвано), я могу прикрепить его только как вкладку, заполняющую все окно. Однако мне нужна система, в которой нет разницы между окном панели инструментов и основным окном. Мне нужно иметь возможность закрепить окна друг под другом в окне панели инструментов так же, как в главном окне.

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

Мне было бы интересно, как бы вы настроили общий дизайн класса для чего-то подобного? Я хотел бы остаться как можно более универсальным, чтобы его можно было использовать для множества различных сценариев.

Поведение пристыковки такое же, как на следующем рисунке. В центре изображения показана область стыковки с перетаскиванием. И внешние изображения, где окно будет привязываться:

альтернативный текст http://img196.imageshack.us/img196/2450/dockingregions.png

Обычно я сталкиваюсь здесь с мэрами: как мне спроектировать программную модель (как сохранить конфигурации стыковки в XAML) и как мне реализовать основные функции. Первым делом я хотел бы иметь симбиоз DockPanel и TabControl. Что-то вроде этого:

<DockTabControl>
  <DockTabItem Dock="FirstLeft">
    <DockTabItem.Header>
        <TextBlock>Tab 1</TextBlock>
    </DockTabItem.Header>
    <!-- Tab 1 content -->
  </DockTabItem>
  <DockTabItem Header="Tab 2" Dock="SecondLeft" DockMode="MergeWithPreviousToTabgroup">
    <!-- Tab 2 content -->
  </DockTabItem>
  <DockTabItem Header="Tab 3" Dock="FirstMiddle">
    <!-- Tab 3 content -->
  </DockTabItem>
</DockTabControl>

Конечно, это пока не имеет смысла. Стыковка не может быть определена таким образом, и проблема окон еще не решена здесь. Но мне нравится идея определения закрепления и групп вкладок, просто определяя некоторые свойства в DockTabItem. Я действительно не хотел бы вводить дополнительные элементы управления, такие как TabGroups или подобные. Мне нравится поведение стыковки в DockPanel, просто определяя порядок дочерних элементов и присоединяемое свойство Dock. Конечно, моя стыковка будет немного более сложной и будет вести себя больше как то, что делает Grid.

Ответы [ 4 ]

14 голосов
/ 13 февраля 2010

Для поддержки сценариев, которые вы иллюстрируете в своем вопросе, достаточно одного DockPanel, поэтому все, что вам нужно написать, это обработчики для OnDragEnter, OnDragOver, OnDragLeave и OnDragDrop. Я обычно использую один обработчик событий, потому что обработка этих четырех событий очень похожа:

OnDragEnter & OnDragOver:

  1. Вычислить, какое ребро и в каком месте в DockPanel элемент будет отброшен
  2. Удалить любого существующего рекламодателя
  3. Добавить прямоугольный рекламный элемент, чтобы показать расположение капли

OnDragLeave:

  1. Удалить всех существующих реклам

OnDragDrop:

  1. Удалить любого существующего рекламодателя
  2. Вычислить, какое ребро и какое место в DockPanel будет уронить предмет
  3. Удалите перетаскиваемый элемент с текущей панели, установите DockPanel. Закрепите его и добавьте на новую панель

Естественно, вы также должны обрабатывать перетаскивание в строке заголовка и вызывать DoDragDrop для исходного объекта.

Две сложности здесь:

  • Решение о том, достаточно ли DockPanel для ваших нужд или вам потребуется более сложная структура данных
  • Убедившись, что геометрические расчеты учитывают все возможные конфигурации окон

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

4 голосов
/ 14 февраля 2010

Существует отличная док-библиотека WPF, опубликованная кем-то на codeproject.com, которая обладает нужной вам функциональностью. Я использовал его однажды, и все прошло довольно гладко.

Проверьте это здесь: http://www.codeproject.com/KB/WPF/WPFdockinglib.aspx

3 голосов
/ 22 февраля 2011

АвалонДок хорош.

http://avalondock.codeplex.com/

Жаль, что вы не можете его использовать;)

0 голосов
/ 12 февраля 2010

WPF уже имеет элементы управления, которые поддерживают стыковку (или этот эффект). Проверьте книгу Адама Натана WPF WPF Unleashed , он покрывает ее в части 2.

...