引言
第三节讲到,可以添加节点并通过后台代码连接端子。在实际的运用过程中通常需要在编辑器界面中去手动拖动端子进行连接,此时需要一个预连接模块,来存储手动拖动时接触的两个端子,并在鼠标松开后进行连接。
1、预连接模块
cs
public partial class PendingConnectionViewModel : ObservableObject
{
//编辑器对象
private readonly EditorViewModel _editor;
//开始 连接端子
private ConnectorViewModel _source;
public PendingConnectionViewModel(EditorViewModel editor)
{
_editor = editor;
}
//记录开始连接端子
[RelayCommand]
private void Start(ConnectorViewModel source)
{
_source = source;
}
//预连接结束时判断 并进行连接
[RelayCommand]
private void Finish(ConnectorViewModel target)
{
if (target != null)
_editor.Connect(_source, target);
}
}
上节说到,连接关系存储在编辑器中,所以这里要传入编辑器对象,用编辑器的Connect方法连接两个端子。
2、编辑器
cs
public partial class EditorViewModel
{
public ObservableCollection<NodeViewModel> Nodes { get; set; } =
new ObservableCollection<NodeViewModel>();
public ObservableCollection<ConnectionViewModel> Connections { get; } =
new ObservableCollection<ConnectionViewModel>();
public PendingConnectionViewModel PendingConnection { get; }
public EditorViewModel()
{
PendingConnection = new PendingConnectionViewModel(this);
var welcome = new NodeViewModel()
{
Title = "Welcome",
Input = new ObservableCollection<ConnectorViewModel>
{
new ConnectorViewModel { Title = "输入" }
},
Output = new ObservableCollection<ConnectorViewModel>
{
new ConnectorViewModel { Title = "输出" }
},
Location = new Point(10, 100)
};
var node2 = new NodeViewModel()
{
Title = "我的第二个节点",
Input = new ObservableCollection<ConnectorViewModel>
{
new ConnectorViewModel { Title = "输入" }
},
Output = new ObservableCollection<ConnectorViewModel>
{
new ConnectorViewModel { Title = "输出" }
}
};
var nodify = new NodeViewModel
{
Title = "To Nodify",
Input = new ObservableCollection<ConnectorViewModel>
{
new ConnectorViewModel { Title = "In" }
}
};
Nodes.Add(welcome);
Nodes.Add(nodify);
Nodes.Add(node2);
Connections.Add(new ConnectionViewModel(welcome.Output[0], nodify.Input[0]));
}
//编辑器中的端子连接方法
public void Connect(ConnectorViewModel source, ConnectorViewModel target)
{
var newConnection = new ConnectionViewModel(source, target);
//检查是否已存在相同的连接
if (!Connections.Contains(newConnection))
{
Connections.Add(newConnection);
}
}
}
2、xaml 绑定
cs
<Grid>
<nodify:NodifyEditor
Name="Editor"
Connections="{Binding Connections}"
ItemsSource="{Binding Nodes}"
PendingConnection="{Binding PendingConnection}">
<nodify:NodifyEditor.DataContext>
<vm:EditorViewModel />
</nodify:NodifyEditor.DataContext>
<nodify:NodifyEditor.ItemTemplate>
<DataTemplate DataType="{x:Type mod:NodeViewModel}">
<nodify:Node
Header="{Binding Title}"
Input="{Binding Input}"
Output="{Binding Output}">
<nodify:Node.InputConnectorTemplate>
<DataTemplate DataType="{x:Type mod:ConnectorViewModel}">
<nodify:NodeInput
Anchor="{Binding Anchor, Mode=OneWayToSource}"
Header="{Binding Title}"
IsConnected="{Binding IsConnected}" />
</DataTemplate>
</nodify:Node.InputConnectorTemplate>
<nodify:Node.OutputConnectorTemplate>
<DataTemplate DataType="{x:Type mod:ConnectorViewModel}">
<nodify:NodeInput
Anchor="{Binding Anchor, Mode=OneWayToSource}"
Header="{Binding Title}"
IsConnected="{Binding IsConnected}" />
</DataTemplate>
</nodify:Node.OutputConnectorTemplate>
</nodify:Node>
</DataTemplate>
</nodify:NodifyEditor.ItemTemplate>
<nodify:NodifyEditor.ConnectionTemplate>
<DataTemplate DataType="{x:Type vm:ConnectionViewModel}">
<nodify:StepConnection Source="{Binding Source.Anchor}" Target="{Binding Target.Anchor}" />
</DataTemplate>
</nodify:NodifyEditor.ConnectionTemplate>
<nodify:NodifyEditor.PendingConnectionTemplate>
<DataTemplate DataType="{x:Type vm:PendingConnectionViewModel}">
<nodify:PendingConnection
AllowOnlyConnectors="True"
CompletedCommand="{Binding FinishCommand}"
StartedCommand="{Binding StartCommand}" />
</DataTemplate>
</nodify:NodifyEditor.PendingConnectionTemplate>
</nodify:NodifyEditor>
</Grid>