我正在尝试实现类似于http://audiomap.tuneglue.net/中观察到的图形的图形节点。 (在此处获取图表在搜索框中输入一些文本(例如:asd)。您将获得一个关系图。)
我可以用一组节点构建图形,我可以移动它们。但问题是我想在拖动节点时将流体移动到其他节点。我尝试过Expression Blend FluidMoveBehaviour。但它并不像我想要的那样完美。
这是我的XAML代码:
<Window x:Class="SpicyNodes.MainWindow" Name="MainWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModel="clr-namespace:SpicyNodes.ViewModels"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:SpicyNodes"
Title="MainWindow" Height="500" Width="500">
<Window.Resources>
<local:GraphItemDataTemplateSelector x:Key="graphItemDataTemplateSelector" ></local:GraphItemDataTemplateSelector>
<CompositeCollection x:Key="Col">
<CollectionContainer Collection="{Binding DataContext.Connectors,Source={x:Reference MainWindow1}}"/>
<CollectionContainer Collection="{Binding DataContext.Nodes,Source={x:Reference MainWindow1}}"/>
</CompositeCollection>
<DataTemplate x:Key="personTemplate" DataType="{x:Type viewModel:Person}">
<Thumb DragDelta="Thumb_Drag" DragCompleted="thumb_DragCompleted" DragStarted="thumb_DragStarted" Name="thumb"
>
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Canvas Margin="-10,-10,10,10">
<Ellipse Height="20" Width="20" Stroke="#696969" StrokeThickness="1" Fill="#353520"
x:Name="Ellipse">
</Ellipse>
<TextBlock Canvas.Top="-20" Canvas.Left="-40" Width="100" FontFamily="Cambria" FontSize="12"
TextAlignment="Center" Text="{Binding Name}"
IsHitTestVisible="False"
/>
</Canvas>
<ControlTemplate.Triggers>
<Trigger Property="IsDragging" Value="True">
<Setter TargetName="Ellipse" Property="Fill" Value="Green"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</DataTemplate>
<DataTemplate x:Key="connectorTemplate" DataType="{x:Type viewModel:Connector}">
<StackPanel>
<Line Stroke="Gray" StrokeThickness="2"
X1="{Binding StartNode.X}" Y1="{Binding StartNode.Y}"
X2="{Binding EndNode.X}" Y2="{Binding EndNode.Y}" x:Name="Line">
</Line>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="0.2*"></RowDefinition>
</Grid.RowDefinitions>
<ItemsControl
ItemTemplateSelector="{StaticResource graphItemDataTemplateSelector}"
Name="items" ItemsSource="{StaticResource Col}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate x:Name="PanelTemplate">
<Canvas Name="canvas1" >
<!--<i:Interaction.Behaviors>
<ei:FluidMoveSetTagBehavior Tag="Element" AppliesTo="Children"/>
</i:Interaction.Behaviors>-->
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
<Button Grid.Row="1" Click="Button_Click" Height="30" Width="50">Add</Button>
</Grid>
MainWindow.cs文件包含:
void _CreateObjectOnCanvas(string Name, double X, double Y)
{
Person node2 = new Person(Name, "", "");
node2.Position = new Point(150, 120);
node2.X = X;
node2.Y = Y;
viewModel.Nodes.Add(node2);
Connector c = new Connector();
c.StartNode = viewModel.Nodes[0];
c.EndNode = node2;
viewModel.Connectors.Add(c);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Random rand = new Random();
var Angle = rand.Next(0, 360);
Angle = (Angle * 7) % 360;
var X = viewModel.Nodes[0].X + 100 * Math.Sin(Angle);
var Y = viewModel.Nodes[0].Y + 100 * Math.Cos(Angle);
if (!_CheckForOverlap(X, Y))
{
var Person = viewModel.CreatePerson(GIndex++);
_CreateObjectOnCanvas(Person.Name, X, Y);
}
}
Person类包含以下内容:
double x;
public override double X
{ get { return x; }
set
{
x = value;
OnPropertyChanged("X");
}
}
double y;
public override double Y
{
get { return y; }
set
{
y = value;
OnPropertyChanged("Y");
}
}
public string Name { get; set; }
public string Occupation { get; set; }
public string ContactInfo { get; set; }
public System.Windows.Point Position { get; set; }
public Person(string name, string occupation, string contact)
{
this.Name = name;
this.Occupation = occupation;
this.ContactInfo = contact;
}
我非常感谢这方面的任何帮助,因为我花了将近2天的时间来完成这项工作。
谢谢。