将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容器的集合数据绑定,希望跟大家交流。也希望对于有同样疑问的朋友有所帮助。

posted @ 2012-04-03 16:51  alan0405  阅读(521)  评论(1编辑  收藏  举报