在筆記(一)中記了點Binding的Path相關, 因為Binding的帶參構造器就只有Path的參數.
所以Path是很重要的, 有了Path, 即使在沒有指定Source的時候, Binding也會隨着UI元素樹一層一層往外找DataContext對象, 判斷是否具有相應的Path, 有就拿來用.
一, DataContext屬性與Binding
筆記(一)中的Binding, 除了控件間的Binding, 其他都是在C#代碼處完成的.
如何在XAML中Binding那些在C#中定義的實例呢?
方法之一就是使用DataContext.
1, 准備一個類
public class Student { public Student(string id, string name, int age) { this.Name = name; this.Id = id; this.Age = age; } public string Id { get; set; } public string Name { get; set; } public int Age { get; set; } }
2, 實例化, 然后賦值給窗體的DataContext
public partial class Window1 : Window { public Window1() { InitializeComponent(); Student stu = new Student("101", "巴爾扎克", 16); this.DataContext = stu ;
}
}
3, 准備XAML
<StackPanel> <TextBlock Text="{Binding Id}" Margin="5" /> <TextBlock Text="{Binding Name}" Margin="5" /> <TextBlock Text="{Binding Age}" Margin="5" /> </StackPanel>
運行, 出現如下界面
這樣就成功了.
於是我朋友說, 那我直接把窗體自己做自己的DataContext, 然后定義的那些屬性都能找到?
汗, 還真是能找到. 於是他說, 那如果我有多個數據源要分別Binding, 就多准備一些窗體的屬性, 那XAML那邊寫起來就簡單了.
汗, 效果的確是能實現, 其他的不談...
下面來試一下
4, 添加window1的屬性並修改實例化部分的代碼
public partial class Window1 : Window { public Window1() { InitializeComponent(); stu = new Student("101", "巴爾扎克", 16);//這邊實例化后賦值的對象是屬性 this.DataContext = this;//這里改成this了 } public Student stu { get; set; } }
5, 修改XAML處的Binding
<StackPanel> <TextBlock Text="{Binding stu.Id}" Margin="5" /> <TextBlock Text="{Binding stu.Name}" Margin="5" /> <TextBlock Text="{Binding stu.Age}" Margin="5" /> </StackPanel>
F5運行, 成功
當然, 在上述示例中如果使用StackPanel的DataContext的話也行.
看到這里是否會覺得很奇怪, 好像跟路由事件的冒泡路由很像?
可惜, 冒泡路由是主動的, 而Binding才能這么牛, 只是作為依賴屬性沒顯示指定DataContext的控件會自動使用其容器的DataContext而已.
測試開始!
還是上面的示例, XAML處給StackPanel指定一個Name="stackPanel", 然后把C#處指定DataContext部分的代碼修改如下
public Window1() { InitializeComponent(); stu = new Student("101", "巴爾扎克", 16); this.DataContext = this; string strBuf = "Wahahaahaha"; stackPanel.DataContext = strBuf; }
F5運行, 發現空白一片...因為這些TextBlock使用的是上一級節點的DataContext, 而StackPanel的DataContext是個string類型, 沒有Path想要的...殘念了
突然想到一個很詭異的情況, 就是DataContext正好就是需要類型, 比如正好是string
那么就會出現
<TextBlock Text="{Binding}" Margin="5" />
這樣詭異的Binding, 此后再遇也就不奇怪啦~