在筆記(一)中記了點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, 此後再遇也就不奇怪啦~