接着上一篇來侃。html
二.實體到控件之間的綁定c#
這兒不知道用實體這個詞恰不恰當,湊活着理解就好了。他能夠是一個類實例,也能夠是一個集合。函數
因此,相應的咱們就引入兩個Demo,第一個介紹用簡單的類做爲做爲數據源,第二個就介紹用一個集合做爲數據源post
廢話很少說,來看demo,我先上代碼,後上分析this
DEMO1:url
XAML頁面spa
<Page.Resources> <local:User x:Key="user"></local:User> </Page.Resources> <Grid> <StackPanel DataContext="{StaticResource user}" HorizontalAlignment="Center"> <TextBlock x:Name="tbID" Text="{Binding Path=ID}"></TextBlock> <TextBlock x:Name="tbName" Text="{Binding Path=Name}"></TextBlock > <TextBlock x:Name="tbGender" Text="{Binding Path=Gender}"></TextBlock> </StackPanel> </Grid>
User類:調試
public class User { public int ID{get;set} public string Name{get;set} public string Gender{get;set;} }
C#代碼:code
public sealed partial class MyPage : Page { public MyPage() { this.InitializeComponent();
User user=Resources["user"] as User; if (user != null) { user.ID = 10000; user.Name = "CQ"; user.Gender = "不明"; } } }
上面兩坨就是所有代碼了,在這兒我說一下執行大概流程。htm
在執行MyPage類的構造函數時,咱們經過User user=Resources["user"] as User拿到定義在MyPage頁面中的靜態資源User類的實例,而後對其賦值,運行程序後,咱們發現控件上顯示出來了
咱們賦值的數據。
其實,咱們在xaml中定義了三個TextBlock控件用來顯示User類中的三個屬性,可是咱們只在他們的binding中只聲明瞭Path,並無指定ElementName,也就是數據源,這時候他們會查找他們的父級
元素的數據源,這個數據源必須含有ID,User,Gender三個屬性。而在他們的父級元素StackPanel中定義了屬性DataContext(數據上下文),它在這兒指明瞭數據源,是誰呢?就是「user」,它定義在靜態
資源中。而後在MyPage類的構造函數中,拿到了類User的實例,爲他賦值後,最後經過數據綁定的技術,他們最終顯示在屏幕上!注意:當他們顯示後,若是人爲修改了user類中的屬性值,這種改變是
不會在界面上顯示出來的。若是想讓它跟着變該怎麼辦?往下看!
在Demo1中的代碼實際是沒有啥實際用途的,想要有用途的,咱們把它改造一下!!!
以前說了,咱們須要在User類實例的屬性值發生改變後,讓改變後的數據也顯示在界面上。因此作以下改動!只須要改動User類就能夠了!
public class User : INotifyPropertyChanged { private int _id; private string _name; private string _gender; public int ID { get { return _id; } set { _id = value; OnPropertyChanged(); } } public string Name { get { return _name; } set { _name = value; OnPropertyChanged(); } } public string Gender { get { return _gender; } set { _gender = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged([CallerMemberName]string propertyName="") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
其實理解仍是比較簡單。試想,提供一種機制,在user屬性改變後,就通知系統說「個人值變了,你丫趕忙給我再界面上表達出來」,那麼這個機制就經過讓User繼承INotifyPropertyChanged這個
接口來實現。
對比這個類和以前的,除了實現了接口INotifyPropertyChanged接口外,還定義了一個公共方法OnPropertyChanged,其次全部的屬性的set方法里加了OnPropertyChanged()方法,用來通知
屬性值發生了改變。
提示小技巧:CallerMemberName特性的做用是在調用OnPropertyChanged方法時,把屬性的名稱做爲參數傳進入,若是不加的話,在調用時就須要手動輸入屬性名稱,這樣出錯的概率就比較大!
置於INotifyPropertyChanged的真正內部原理,請msdn!...實際上是我不太懂!
好了,作了如上一番修改後,就是先咱們須要的功能了!
DEMO2
此次咱們玩個有用的,吧一個集合中的數據綁定到一個列表中!
先上代碼!!!
xaml:
<StackPanel> <Button Content="改變" Click="Button_Click"></Button> <ItemsControl x:Name="itemsControl" ItemsSource="{Binding}"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding ID,Mode=OneWay}"/> <TextBlock Text="{Binding Name,Mode=OneWay}" ></TextBlock> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel>
product:
public class Product { private int _id; private string _name; public int ID { get { return _id; } set { _id = value; } } public string Name { get { return _name; } set { _name = value; } } }
c#:
public sealed partial class MyPage : Page { List<Product> list = null; public MyPage() { this.InitializeComponent(); list = new List<Product> { new Product { ID=1,Name="土豆" }, new Product{ ID=2,Name="馬鈴薯"}, new Product{ ID=3,Name="洋芋"} }; itemsControl.ItemsSource = list; } private void Button_Click(object sender, RoutedEventArgs e) { if (list != null) { list.Add(new Product { ID = 4, Name = "Potato" }); } } }
這是運行結果。先不要在乎那個「改變」按鈕。
此次定義了一個ItemsControl列表控件,而且對其ItemTemplate 定義了一個模板,知識仍是數據綁定。不懂能夠看個人這篇文章DataTemplate和ControlTemplate聯繫與區別
而後定義了一個泛型集合List<Product>,添加了三條數據後,把它設置爲ItemsControl的數據源,注意這兒不用DataContext設置,用ItemSource屬性!(而這區別能夠百度!)
以後運行程序,發現數據已經成功顯示在界面上了。
到這兒,已經實現瞭如何把一個集合中的數據顯示在一個列表控件中!
而的「改變」按鈕的做用是想List中添加一條數據,但在點擊後,界面上並無反應,可是經過調試發現,數據的確添加到了List中,知識沒有顯示出來而已,結合咱們以前一篇博文,
應該能猜到,這兒缺乏某種通知機制。當咱們把List<Product>換爲ObservableCollection<Product>後,會發現可以改變數據了。
經過查看定義發現ObservableCollection<T>實現了接口INotifyCollectionChanged, INotifyPropertyChanged,正是這兩個接口提供了這種通知機制!
至此。個人心得就完了。。但總感受講的不夠,不清楚。之後把其中的小技巧在發篇博文談談。