天天看點

WPF的Binding學習筆記(三)

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