這個一節都是在講一個數據綁定的示例。
功用:輸入姓和名,點擊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);