這個一節都是在講一個資料繫結的樣本。
功用:輸入姓和名,點擊Add按鈕,ListBox增加一條記錄,永遠是字串“name: nick”;ListBox原先有3條不同記錄,選中ListBox一條記錄,兩個輸入框姓和名相應變化。
技術分析:2個類,一個xaml,一個一個分析。
1)Nickname類, 實體類,提供兩個屬性Nick和Name,還有一個PropertyChanged事件。實現了INotifyPropertyChanged 介面(從而可以使用PropertyChangedEventArgs事件,在給屬性賦值時,激發該事件,通知外界customer——觀察者xaml介面相應變化,即資料同步。
2)Nicknames類,實現ObservableCollection<Nickname>介面,類下不再提供自訂的東西,因為實現該介面後,這個類成為了一個Nickname的強型別集合,並且可以將資料的add和remove通知customer,從而資料同步。
注意,INotifyPropertyChanged 適用於單個的類屬性,ObservableCollection適用於監視某一堆的資料是否發生變化(add/remove),這是二者的區別。
3)window1.xaml.cs 後台類
提供內部集合names,Nicknames類型。
在建構函式中,先初始化以及綁定button_Click事件,然後執行個體化names變數,最後綁定names到前台的DockPanel控制項:
dockPanel.DataContext = this.names;
DataContext屬性設定是關鍵,感覺和過去的綁定差不多。
Button每按一次,都會在names中加一條同樣的資料nick: name
4)window1.xaml 前台
<DockPanel x:Name="dockPanel">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center">Name: </TextBlock>
<TextBox Text="{Binding Path=Name}" />
<TextBlock VerticalAlignment="Center">Nick: </TextBlock>
<TextBox Text="{Binding Path=Nick}" />
</StackPanel>
<Button DockPanel.Dock="Bottom" x:Name="addButton">Add</Button>
<ListBox
ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True" />
</DockPanel>
可以看到前台具體資料區段是怎麼綁定的:
<TextBox Text="{Binding Path=Name}" />
<ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" />
IsSynchronizedWithCurrentItem="True"確保了DockPanel中的TextBox 與ListBox 資料是同步的。但是這樣子ListBox中的資料得到的都是同樣的字串
namespace.Nickname——同過去的資料繫結機制,缺少模板,要改寫成這樣:
<ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock
TextContent="{Binding Path=Name}" />:
<TextBlock
TextContent="{Binding Path=Nick}" />
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
這一節沒有講ListBox中3行初始資料是從哪裡以及如何載入的——將在1.8節詳細討論。
補充:
因為<TextBox Text="{Binding Path=Name}" /> 可以改寫為
TextBox.Text><Binding Path="Name" /></TextBox.Text>
從而等價於下列後台代碼:
Binding binding = new Binding( );binding.Path = "Name";textbox1.Text = binding.ProvideValue(textbox1, TextBox.TextProperty);