我試圖執行拖放方法來創建圖表中的關係,直接與圖表工具SQL Server Management Studio一致。例如,在下圖中,用戶將從User
實體拖動CustomerID
到Customer
實體,並在兩者之間創建外鍵關係。在WPF中拖放的繪製圖圓弧
關鍵的預期功能是當用戶按照鼠標執行拖動操作時,繪製臨時弧路徑。移動的實體或關係一旦創建不是我遇到的問題。
對應於實體上圖上的一些參考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
被綁定到視圖模型,並且Canvas
上的實體和關係又被綁定到相應的視圖模型。與整體框圖一些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爲的entites和關係:
<!-- 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更改基於IsDragging的Cursor
和Adorner
可見性,並且可以使用DragItem進行放置操作。
(但是,我期待獎項的另一個有趣的方法賞金請評論,如果需要更多的信息或代碼來澄清這個問題。)
編輯:較低的優先級,但是我仍然在尋找更好的解決方案來實現拖放圖表方法。希望在開源Mo+ Solution Builder中實施更好的方法。
謝謝亞當。我確實使用了Thumb控件來移動實體和關係,並在渲染後調整實體的大小。在這種情況下,我不認爲我可以使用大拇指,因爲在拖動過程中正在繪製弧路徑,然後將其作爲控件放置。除非你知道一個竅門! – 2011-06-16 04:22:05