将ObservableCollection(Of T) 数据 绑定到 Canvas
初识 Wpf ,感觉其功能的强大,所以着手做一个MindMap(脑图)工具,
构思将自定义控件Node节点,放入一个Canvas容器中,表示脑图的主题节点。
将Node装入Canvas并不难,但是仍然考虑用绑定的方式,使UI与Model解耦。
继承自ItemsControl的Listbox当然可以轻松绑定以ObservableCollection形式储存的模型数据。
但是Canvas并不是继承自ItemsContorl的,无法直接绑定ObservableCollection对象。
上午请教了@{Prism}兄弟,了解到将Canvas装入ItemsControl.ItemsPanel的方式,遂
动手做了一个实验。
上代码
Xaml文件
1: <Window x:Class="MainWindow" x:Name="mainWindow"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: Title="MainWindow" Height="350" Width="525">
5: <Grid>
6: <ItemsControl Name="ic" ItemsSource="{Binding ElementName=mainWindow, Path=NodeList}">
7: <ItemsControl.ItemTemplate>
8: <DataTemplate>
9: <TextBlock Margin="{Binding Left}" Background="Red" Text="{Binding Title}"></TextBlock>
10: </DataTemplate>
11: </ItemsControl.ItemTemplate>
12:
13: <ItemsControl.ItemsPanel>
14: <ItemsPanelTemplate>
15: <Canvas Background="LightBlue"/>
16: </ItemsPanelTemplate>
17: </ItemsControl.ItemsPanel>
18: </ItemsControl>
19: <Button Margin="203,223,219,67" Click="Button_Click">Move</Button>
20: </Grid>
21: </Window>
在Xaml文件中,黄色部分是ItemsControl的数据模版,其中绑定Node类的Title属性。
另将Margin属性绑定到Left是为了实验,单个控件的移动。因为我要做的是脑图。
绿色部分,就是关键所在了,将Canvas装入ItemsPanel。
主窗口后台代码
1: Imports System.Collections.ObjectModel
2:
3: Class MainWindow
4: '
5: 'NodeList As ObservableCollection(Of Node)
6: '
7: Private mNodeList As ObservableCollection(Of Node)
8: Public ReadOnly Property NodeList() As ObservableCollection(Of Node)
9: Get
10: If mNodeList Is Nothing Then
11: Return New ObservableCollection(Of Node)
12: End If
13: Return mNodeList
14: End Get
15:
16: End Property
17:
18: Public Sub New()
19: mNodeList = New ObservableCollection(Of Node)
20: mNodeList.Add(New Node("Hello"))
21: ' 此调用是设计器所必需的。
22: InitializeComponent()
23:
24: ' 在 InitializeComponent() 调用之后添加任何初始化。
25:
26: End Sub
27:
28: Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
29: mNodeList.Item(0).Left = 100.0
30: End Sub
31: End Class
并没有出奇的地方,正常设定。
Node类的代码
1: Public Class Node
2: Inherits DependencyObject
3:
4:
5: #Region " Title DependencyProperty "
6: ''' <summary>
7: ''' PropertyComment
8: ''' </summary>
9: ''' <remarks></remarks>
10: Public Shared ReadOnly TitleProperty As DependencyProperty = _
11: DependencyProperty.Register(
12: "Title", GetType(String), GetType(Node), New UIPropertyMetadata(""))
13:
14: Public Property Title() As String
15: Get
16: Return GetValue(TitleProperty)
17: End Get
18: Set(ByVal Value As String)
19: SetValue(TitleProperty, Value)
20: End Set
21: End Property
22: #End Region
23:
24: #Region " Left DependencyProperty "
25: ''' <summary>
26: ''' PropertyComment
27: ''' </summary>
28: ''' <remarks></remarks>
29: Public Shared ReadOnly LeftProperty As DependencyProperty = _
30: DependencyProperty.Register(
31: "Left", GetType(Double), GetType(Node), New PropertyMetadata( _
32: 0.0, New PropertyChangedCallback(AddressOf LeftPropertyChanged_CallBack)))
33:
34: Public Property Left() As Double
35: Get
36: Return GetValue(LeftProperty)
37: End Get
38: Set(ByVal Value As Double)
39: SetValue(LeftProperty, Value)
40: End Set
41: End Property
42:
43: Public Shared Sub LeftPropertyChanged_CallBack(ByVal dp As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
44:
45: End Sub
46: #End Region
47:
48: Public Sub New(ByVal t As String)
49: Title = t
50: End Sub
51:
52: End Class
53:
定义了两个依赖属性用于绑定。
通过本例,实现了Canvas容器的集合数据绑定,希望跟大家交流。也希望对于有同样疑问的朋友有所帮助。