Я пытаюсь применить метод перетаскивания для создания отношений на диаграмме , непосредственно аналогичный SQL Server Management Studio инструменты построения диаграмм. Например, на иллюстрации ниже пользователь перетащит CustomerID
из сущности User
в сущность Customer
и создаст между ними отношения внешнего ключа.
Ключевой желаемой функцией является то, что временная дуга будет нарисована, когда пользователь выполняет операцию перетаскивания, следуя за мышью. Я не сталкиваюсь с проблемой перемещения сущностей или отношений после их создания.
Некоторые ссылки на XAML, соответствующие сущности на диаграмме выше:
Мой текущий подход к выполнению этого заключается в следующем:
1) Инициировать операция перетаскивания в дочернем элементе управления объекта, например:
protected override void OnPreviewMouseMove(MouseEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed)
{
dragStartPoint = null;
}
else if (dragStartPoint.HasValue)
{
Point? currentPosition = new Point?(e.GetPosition(this));
if (currentPosition.HasValue && (Math.Abs(currentPosition.Value.X - dragStartPoint.Value.X) > 10 || Math.Abs(currentPosition.Value.Y - dragStartPoint.Value.Y) > 10))
{
DragDrop.DoDragDrop(this, DataContext, DragDropEffects.Link);
e.Handled = true;
}
}
}
2) Создайте украшение соединителя, когда операция перетаскивания покидает объект, например:
protected override void OnDragLeave(DragEventArgs e)
{
base.OnDragLeave(e);
if (ParentCanvas != null)
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(ParentCanvas);
if (adornerLayer != null)
{
ConnectorAdorner adorner = new ConnectorAdorner(ParentCanvas, BestConnector);
if (adorner != null)
{
adornerLayer.Add(adorner);
e.Handled = true;
}
}
}
}
3) Нарисуйте путь дуги при перемещении мыши украшение коннектора, например:
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
if (!IsMouseCaptured) CaptureMouse();
HitTesting(e.GetPosition(this));
pathGeometry = GetPathGeometry(e.GetPosition(this));
InvalidateVisual();
}
else
{
if (IsMouseCaptured) ReleaseMouseCapture();
}
}
Схема Холст
привязан к модели представления, а объекты и отношения на Холсте
, в свою очередь, привязаны к соответствующим моделям представления. Некоторые XAML , относящиеся к общей диаграмме:
и DataTemplate
для сущностей и отношений:
Проблема: Проблема в том, что как только начинается операция перетаскивания, движения мыши больше не отслеживаются, а средство оформления соединителя не может рисовать дугу, как в других контекстах. Если я отпущу мышь и щелкну снова, дуга начнет рисоваться, но затем я потеряю исходный объект. Я пытаюсь придумать способ передать исходный объект вместе с движением мыши.
Bounty: Возвращаясь к этой проблеме, в настоящее время я планирую не использовать перетаскивание напрямую для этого. В настоящее время я планирую добавить DragItem и IsDragging DependencyProperty
для элемента управления диаграммой, который будет удерживать перетаскиваемый элемент и отмечать, происходит ли операция перетаскивания. Затем я мог бы использовать DataTrigger
s для изменения видимости Cursor
и Adorner
на основе IsDragging, а также мог бы использовать DragItem для операции перетаскивания.
(Но, Я хочу наградить награду за другой интересный подход. Прокомментируйте, если требуется дополнительная информация или код, чтобы прояснить этот вопрос.)
Изменить: Низкий приоритет, но я все еще ищу лучшее решение для подхода к построению диаграмм перетаскиванием.Хотите реализовать лучший подход в Mo + Конструктор решений с открытым исходным кодом.