ObservableCollection(Of T)データをCanvasにバインドする

18979 ワード

Wpfを初めて知り、その機能の強さを感じたので、MindMap(脳図)ツールに着手しました.
カスタムコントロールノードをCanvasコンテナに入れ、脳図を表すトピックノードを想定します.
 
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>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Xamlファイルでは、黄色の部分はItemsControlのデータテンプレートで、ノードクラスのTitleプロパティをバインドします.
さらにMargin属性をLeftにバインドしたのは実験のためであり,単一のコントロールの移動である.私がしなければならないのは脳図だからです.
 
緑の部分がポイントで、CanvasをItems Panelに入れます.
 
メインウィンドウバックグラウンドコード
   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

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
奇抜なところはなく、正常に設定されています.
 
ノードクラスのコード
   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:   

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
バインドに使用する2つの依存プロパティが定義されています.
 
この例では,Canvasコンテナの集合データバインドを実現し,皆さんとのコミュニケーションを望んでいる.同じような疑問を持っている友人にも助けてほしい.