ArxisStudio.DesignEditor
The foundational control for building visual form designers and GUI builders in Avalonia UI. Provides a high-performance infinite canvas with a precision-rendered, DPI-aware grid system designed for laying out UI controls and layouts. Features seamless zooming and panning, making it the perfect workspace for your next IDE-like tool.
Install / Use
/learn @Arxis-Team/ArxisStudio.DesignEditorREADME
ArxisStudio.DesignEditor
ArxisStudio.DesignEditor — это библиотека для Avalonia UI, предназначенная для построения визуальных редакторов, form designer'ов, layout editor'ов и других IDE-подобных инструментов.
Библиотека предоставляет:
- бесконечную поверхность с панорамированием и зумом
- прямоугольное и множественное выделение
- контейнеры элементов с drag-and-drop и resize
- editor-level overlay-слои для рамок выделения, marquee и selection handles
- систему attached-свойств для позиционирования
- DPI-aware трансформации для фона, сетки и оверлеев
- демо-приложение с типовым сценарием интеграции
Структура решения
src/— библиотека контроловsamples/DesignEditor.Demo/— демонстрационное Avalonia-приложениеArxisStudio.DesignEditor.sln— solution
Основные компоненты
DesignEditor
Главный контрол редактора. Наследуется от SelectingItemsControl и отвечает за:
- позицию viewport через
ViewportLocation - масштаб через
ViewportZoom,MinZoom,MaxZoom - выделение через
SelectionиSelectedItems - overlay-систему редактора поверх содержимого
- состояния взаимодействия: idle, selecting, panning
- групповое перемещение выбранных элементов
- навигацию viewport через
CenterOn(...)иCenterOnItem(...) - вписывание области или элемента через
FitToView(...)
Текущий template DesignEditor уже разделен на слои:
ItemsLayer— реальное содержимое редактора иDesignEditorItemSelectionOverlayLayer—SelectionAdorner, secondary outlines, group outline и selection handlesInteractionOverlayLayer— временные interaction overlays, которые живут только во время действия пользователя
PART_InteractionOverlayLayer предназначен не для постоянного editor chrome, а для временной визуализации процессов:
- marquee selection rectangle
- snap lines и alignment guides
- drag / resize preview
- insertion markers
- hover preview и временные измерительные подсказки
Сейчас на нем уже живет прямоугольник marquee-selection. В дальнейшем этот слой будет точкой расширения для guides, snapping и preview overlays.
DesignEditorInputGestures
Объект конфигурации input gestures редактора. Позволяет настраивать горячие клавиши и модификаторы взаимодействия:
- из AXAML
- через
Style - через code-behind
- через binding / MVVM
Сейчас в нем уже доступен:
PanButton/PanModifiers— кнопка мыши и модификаторы для старта панорамированияMarqueeButton/MarqueeModifiers— кнопка мыши и модификаторы для старта marquee-selection по пустой областиZoomModifiers— модификаторы для wheel-zoomContainerInteractionModifiers— модификаторы, которые принудительно переключают selection, drag и resize на уровеньDesignEditorItemAdditiveSelectionModifiers— модификаторы, которые включают additive selection
DesignEditorInteractionOptions
Объект runtime-параметров взаимодействия редактора, которые не относятся к gesture policy:
ZoomStep— шаг wheel-zoomDragStartThreshold— порог старта drag в пикселяхResizeMinSize— минимальный размер при resize
DesignSelectionTarget
Публичный контракт выбранного target в редакторе:
Container—DesignEditorItem, которому принадлежит targetTarget— фактически выбранныйControlScope— уровень выбора (ContainerилиNestedTarget)DisplayName— диагностическое имя target для UI/логов
DesignEditor предоставляет:
PrimarySelectionTarget— текущий primary targetSelectedDesignTargets— снимок всех выбранных targetsSelectedDesignTargetsCount— количество выбранных targets
DesignInteraction
ArxisStudio.Attached.DesignInteraction предоставляет attached-политики редактирования для designer targets:
DesignInteraction.ResizePolicy— какие стороны/направления разрешены для resize (None,Left,Top,Right,Bottom,Horizontal,Vertical,All)DesignInteraction.MovePolicy— по каким осям разрешено перемещение (None,X,Y,Both)
Политики применяются как к одиночному target, так и к group interaction:
- если направление запрещено
ResizePolicy, соответствующие handles неактивны и resize не выполняется - если
MovePolicyограничивает оси, drag сохраняет только разрешенные компоненты delta - если
MovePolicy = None, target не перемещается
Что это дает в конструкторе программ:
- блокировку resize/drag для системных или layout-driven контролов без кастомной логики в каждом шаблоне
- ограничение перемещения по одной оси (
XилиY) для splitters, линий, панелей и других специализированных элементов - ограничение resize по сторонам (
Horizontal,Verticalили отдельные края) для предсказуемого form-designer UX - единый контракт ограничений для одиночного выбора, nested multi-selection и групповых операций
- снижение риска случайного редактирования критичных узлов в сложных формах
DesignEditor Context API
DesignEditor теперь предоставляет editor-level API для контекстных действий, не привязанный к конкретному UI:
DesignEditorContextRequest— снимок контекста (Scope,Target,Selection,WorldPoint,ViewportPoint,ScreenPoint,Modifiers,Source)DesignEditorContextScope— область вызова (Surface,Container,NestedTarget,Selection)DesignEditorContextAction— описание действия (header, command, icon, separator, submenu)IDesignEditorContextActionProvider— провайдер действий, который строит меню по текущему requestIDesignEditorContextPresenter— абстракция presenter-слоя (отрисовка действий)ContextMenuContextPresenter— встроенный presenter по умолчанию (AvaloniaContextMenu)DesignEditor.ContextActionProviders— коллекция подключенных провайдеровDesignEditor.ContextPresenter— текущий presenter контекстных действийDesignEditor.ContextMenuRequesting— pre-show событие (можно отменить открытие или полностью переопределить показ черезHandled)DesignEditor.ContextMenuResolved— post-resolution событие для логирования/аналитикиDesignEditor.RequestContextAsync(...)— программный вызов контекстного меню
Текущий встроенный presenter использует ContextMenu (Avalonia). Контракт Request/Action/Provider остаётся UI-agnostic, поэтому на следующем этапе можно добавить MenuFlyout/ContextFlyout без изменения доменного API.
Базовые правила scope-резолва:
- right-click по пустому пространству
DesignSurface=>Surface - right-click по
DesignEditorItem(container target) =>Container - right-click по nested target =>
NestedTarget - right-click по выбранному элементу в multi-selection =>
Selection - right-click по nested target сначала переводит этот target в активный selection target (без additive-toggle), после чего открывает контекстное меню
DesignEditorItem
Контейнер элемента редактора, который создается автоматически для каждого item'а. Добавляет:
- состояние выделения
- перетаскивание
- привязку позиции через
Location - визуальные состояния
:selected,:dragging,:resizing
Начиная с текущей версии DesignEditorItem больше не рисует selection frame и resize handles внутри собственного шаблона. Эти editor overlays вынесены на уровень DesignEditor.
Внешний вид selection overlays настраивается через ресурсы и темы SelectionAdorner, а не через item-level свойства контейнера.
Layout
ArxisStudio.Attached.Layout предоставляет attached-свойства позиционирования:
Layout.X/Layout.Y— локальные координаты относительно непосредственного родителяLayout.DesignX/Layout.DesignY— глобальные координаты относительно поверхности дизайнаLayout.IsTracked— принудительное постоянное отслеживание позиции
AbsolutePanel
Панель компоновки, используемая поверхностью редактора. Поддерживает:
- абсолютное позиционирование через
Layout.X/Layout.Y - fallback на
HorizontalAlignment/VerticalAlignment, если координаты не заданы - вычисление
Extentдля всех дочерних элементов
Быстрый старт
1. Подключите библиотеку
Добавьте ProjectReference или PackageReference на ArxisStudio.DesignEditor.
2. Подключите темы контролов
В ресурсах приложения:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="avares://ArxisStudio.DesignEditor/Themes/ArxisStudioDesignEditorTheme.axaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Структура тем библиотеки теперь разделена на слои:
Themes/ArxisStudioDesignEditorTheme.axaml— единая точка входа темы библиотекиThemes/Resources/DesignEditorResources.axaml— lightweight styling resourcesThemes/Styles/*.axaml—ControlThemeконкретных контролов
Это позволяет кастомизировать цвета, толщины, размеры ручек и другие визуальные параметры через ресурсы без копирования шаблонов контролов.
Основные кисти библиотеки теперь определяются через ThemeDictionaries, поэтому Light и Dark варианты могут отличаться без дублирования ControlTheme.
Дополнительно SelectionAdorner использует lightweight resource keys по ролям и состояниям:
DesignEditor.SelectionAdorner.Primary*DesignEditor.SelectionAdorner.Secondary*DesignEditor.SelectionAdorner.Group*DesignEditor.SelectionAdorner.Handle*DesignEditor.SelectionAdorner.Locked*
Это позволяет менять внешний вид Primary, Secondary, Group, Locked, PointerOver и Pressed состояний без копирования ControlTheme.
DesignEditor больше не держит три отдельные theme-обертки для selection overlays: роли задаются через SelectionAdorner.Role, а внешний вид определяется базовой темой SelectionAdorner и соответствующими ресурсами.
3. Привяжите редактор к вашей коллекции элементов
<design:DesignEditor ItemsSource="{Binding Nodes}"
SelectedItems="{Binding SelectedNodes}"
SelectionMode="Multiple"
ViewportZoom="{Binding Zoom, Mode=TwoWay}">
<design:
