如何綁定無法繼承DataContext之物件屬性 (MVVM)
緣由
客戶希望在ListView中加上CheckBox提供用戶選取需要刪除的資料,並須在Header上也加上一個CheckBox來處理全選的情況。因為全選刪除後希望Header上的CheckBox可以恢復Uncheck狀態,所以想將資料綁定至Header CheckBox的IsChecked屬性中,讓ViewModel在處理刪除作業結束後透過綁定的資料來調整CheckBox狀態回復至Uncheck。
ViewModel
WPF XAML
狀況出現
經過測試後發現DataContext(MainViewModel)中IsAllSelected(資料來源)是無法直接被Binding到CheckBox的IsChecked屬性。後來才發現WPF中DataContext並不會全部被繼承到所有的Element中,由於GridViewColumn是非隸屬Visual Tree,所以並不會繼承DataContext也沒有辦法對其屬性資料進行Binding。
解決方式
請參考以下資訊建立繼承自Freezable的BindingProxy類別,透過此類別來橋接DataContext供CheckBox作為Binding資料來源。
Thomas Levesque: How to bind to data when the DataContext is not inherited
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
再來稍微調整一下XAML即可
參考資料
http://www.codeproject.com/Articles/27432/Artificial-Inheritance-Contexts-in-WPF
http://msdn.microsoft.com/en-us/library/system.windows.freezable.aspx
希望此篇文章可以幫助到需要的人
若內容有誤或有其他建議請不吝留言給筆者喔 !