gpt4 book ai didi

wpf - 在 WPF 中通过拖放绘制图表弧

转载 作者:行者123 更新时间:2023-12-02 14:43:10 24 4
gpt4 key购买 nike

我正在尝试执行 在图表中创建关系的拖放方法 , 直接类似于 SQL Server Management Studio图表工具。例如,在下图中,用户将拖动 CustomerID来自 User Customer 的实体实体并在两者之间创建外键关系。

所需的关键功能是当用户执行拖动操作时,将绘制一个临时的弧形路径,跟随鼠标。创建后移动实体或关系不是我遇到的问题。

Entity–relationship diagram

一些引用 XAML 对应于上图中的一个实体:

<!-- Entity diagram control -->
<Grid MinWidth="10" MinHeight="10" Margin="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*" ></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="0" IsHitTestVisible="False" Background="{StaticResource ControlDarkBackgroundBrush}">
<Label Grid.Row="0" Grid.Column="0" Style="{DynamicResource LabelDiagram}" Content="{Binding DiagramHeader, Mode=OneWay}" />
</Grid>
<ScrollViewer Grid.Row="1" Grid.Column="0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Background="{StaticResource ControlBackgroundBrush}" >
<StackPanel VerticalAlignment="Top">
<uent:EntityDataPropertiesDiagramControl DataContext="{Binding EntityDataPropertiesFolder}" />
<uent:CollectionEntityPropertiesDiagramControl DataContext="{Binding CollectionEntityPropertiesFolder}" />
<uent:DerivedEntityDataPropertiesDiagramControl DataContext="{Binding DerivedEntityDataPropertiesFolder}" />
<uent:ReferenceEntityPropertiesDiagramControl DataContext="{Binding ReferenceEntityPropertiesFolder}" />
<uent:MethodsDiagramControl DataContext="{Binding MethodsFolder}" />
</StackPanel>
</ScrollViewer>
<Grid Grid.RowSpan="2" Margin="-10">
<lib:Connector x:Name="LeftConnector" Orientation="Left" VerticalAlignment="Center" HorizontalAlignment="Left" Visibility="Collapsed"/>
<lib:Connector x:Name="TopConnector" Orientation="Top" VerticalAlignment="Top" HorizontalAlignment="Center" Visibility="Collapsed"/>
<lib:Connector x:Name="RightConnector" Orientation="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Visibility="Collapsed"/>
<lib:Connector x:Name="BottomConnector" Orientation="Bottom" VerticalAlignment="Bottom" HorizontalAlignment="Center" Visibility="Collapsed"/>
</Grid>
</Grid>

我目前这样做的方法是:

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();
}
}

Canvas绑定(bind)到 View 模型, Canvas 上的实体和关系依次绑定(bind)到各自的 View 模型。一些 XAML整体图的相关资料:
<ItemsControl ItemsSource="{Binding Items, Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<lib:DesignerCanvas VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
<Setter Property="Canvas.Width" Value="{Binding Width}"/>
<Setter Property="Canvas.Height" Value="{Binding Height}"/>
<Setter Property="Canvas.ZIndex" Value="{Binding ZIndex}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>

DataTemplate s 用于实体和关系:
<!-- diagram relationship -->
<DataTemplate DataType="{x:Type dvm:DiagramRelationshipViewModel}">
<lib:Connection />
</DataTemplate>
<!-- diagram entity -->
<DataTemplate DataType="{x:Type dvm:DiagramEntityViewModel}">
<lib:DesignerItem>
<lib:EntityDiagramControl />
</lib:DesignerItem>
</DataTemplate>

问题:问题是一旦拖动操作开始,鼠标移动就不再被跟踪,并且连接器装饰器无法像在其他上下文中那样绘制弧线。如果我释放鼠标并再次单击,则弧线开始绘制,但随后我丢失了源对象。我试图想办法结合鼠标移动来传递源对象。

赏金:回到这个问题,我目前计划不直接使用拖放来执行此操作。我目前计划添加一个 DragItem 和 IsDragging DependencyProperty对于图表控件,它将保存被拖动的项目,并标记是否正在发生拖动操作。然后我可以使用 DataTrigger s 更改 CursorAdorner基于 IsDragging 的可见性,并且可以使用 DragItem 进行放置操作。

(但是,我希望奖励另一种有趣的方法。如果需要更多信息或代码来澄清这个问题,请发表评论。)

编辑:优先级较低,但我仍在寻找更好的拖放图表方法解决方案。想在开源中实现更好的方法 Mo+解决方案生成器。

最佳答案

我想你会想要查看 WPF Thumb 控件。它将其中的一些功能封装在一个方便的包中。

这是 MSDN 文档:

http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.thumb.aspx

这是一个例子:

http://denisvuyka.wordpress.com/2007/10/13/wpf-draggable-objects-and-simple-shape-connectors/

不幸的是,我在这方面没有很多经验,但我确实认为这就是你要找的。祝你好运!

关于wpf - 在 WPF 中通过拖放绘制图表弧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6361857/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com