引言
Nodify有三层结构,编辑器Editor,节点Node和连接组件Connection,上节介绍了节点和编辑器,本节介绍连接组件。连接组件用于保存节点中连接端子的连接关系,并随节点的拖动改变。
1、连接组件
连接组件存储一个连接关系,包含源和目标
public class ConnectionViewModel
{
public ConnectorViewModel Source { get; set; }
public ConnectorViewModel Target { get; set; }
}
2、连接端子
连接端子有它的名称和位置锚点,其中用到一个MVVM工具包http://t.csdnimg.cn/scDXnhttp://t.csdnimg.cn/scDXn我们拖动节点时连接端子需要跟随移动,连接线也应随之改变,所以需要记录其位置锚点,在xaml中会将其绑定到节点的依赖属性Anchor上,此外还有一个连接状态属性
public partial class ConnectorViewModel : ObservableObject
{
public string Title { get; set; }
[ObservableProperty]
private Point _anchor;
[ObservableProperty]
private bool _isConnected;
}
3、编辑器
在编辑器中不仅要存储所有节点,还需要存储节点的连接关系
public ObservableCollection<ConnectionViewModel> Connections { get; } =
new ObservableCollection<ConnectionViewModel>();
public partial class EditorViewModel
{
public ObservableCollection<NodeViewModel> Nodes { get; set; } =
new ObservableCollection<NodeViewModel>();
public ObservableCollection<ConnectionViewModel> Connections { get; } =
new ObservableCollection<ConnectionViewModel>();
public EditorViewModel()
{
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 nodify = new NodeViewModel
{
Title = "To Nodify",
Input = new ObservableCollection<ConnectorViewModel>
{
new ConnectorViewModel { Title = "In" }
}
};
Nodes.Add(welcome);
Nodes.Add(nodify);
Connections.Add(new ConnectionViewModel(welcome.Output[0], nodify.Input[0]));
}
}
4、xaml绑定
<Grid>
<nodify:NodifyEditor
Name="Editor"
Connections="{Binding Connections}"
ItemsSource="{Binding Nodes}">
<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>
</Grid>