2013-10-03 159 views
0

我想在Datagrid中使用枚舉。讓我告訴你兩種可行的方法。 首先,我在DataGrid內部創建一個ComboBox,DataContext.MyOptions返回一列所有enum值的字符串。將ViewModel屬性綁定到DataGridComboBoxColum

<DataGridTemplateColumn Header="Enum1"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <ComboBox ItemsSource="{Binding DataContext.MyOptions, RelativeSource={RelativeSource AncestorType=Window}}" 
         SelectedItem="{Binding Enum1, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource MyConverter}}" /> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 

下一個我試圖使用DataGridComboBoxColumn,但得到這個工作我必須添加ElementStyle和EditingElementStyle

<DataGridComboBoxColumn Header="Enum1" Width="*" 
         SelectedItemBinding="{Binding Enum1, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource MyConverter}}"> 
    <DataGridComboBoxColumn.ElementStyle> 
     <Style TargetType="ComboBox"> 
      <Setter Property="ItemsSource" Value="{Binding Path=DataContext.MyOptions, RelativeSource={RelativeSource AncestorType=Window}}" /> 
     </Style> 
    </DataGridComboBoxColumn.ElementStyle> 
    <DataGridComboBoxColumn.EditingElementStyle> 
     <Style TargetType="ComboBox"> 
      <Setter Property="ItemsSource" Value="{Binding Path=DataContext.MyOptions, RelativeSource={RelativeSource AncestorType=Window}}" /> 
     </Style> 
    </DataGridComboBoxColumn.EditingElementStyle> 

</DataGridComboBoxColumn> 

現在的問題是,爲什麼(我從什麼地方抄了一遍)下面不行。該列顯示爲空,但值在那裏。

<DataGridComboBoxColumn Header="Enum1" Width="*" 
         ItemsSource="{Binding Path=DataContext.MyOptions, RelativeSource={RelativeSource AncestorType=Window}}" 
         SelectedItemBinding="{Binding Enum1, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource MyConverter}}"> 
</DataGridComboBoxColumn> 

在輸出窗口我看到了以下錯誤:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=DataContext.MyOptions; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=59316889); target property is 'ItemsSource' (type 'IEnumerable') 

回答

2

DataGrid Columns dont come under the visualtree of their parent。這就是爲什麼they cannot inherit the DataContext從父母或他們可以參考祖先。

另一方面,DataGrid行和單元格屬於visualtree,因此可以查找祖先並繼承DataContext。

爲了綁定列,您需要use the BindingProxy

要做到這一點,你可以做的是在你的窗口資源定義一個資源爲

public class BindingProxy : Freezable 
{ 
    #region Overrides of Freezable 

    protected override Freezable CreateInstanceCore() 
    { 
     return new BindingProxy(); 
    } 

    #endregion 

    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)); 
} 

<DataGrid.Resources> 
    <local:BindingProxy x:Key="ProxyElement" Data="{Binding}" /> 
</DataGrid.Resources> 

,然後使用這個元素來在列綁定像

<DataGridComboBoxColumn Header="Enum1" Width="*" 
         ItemsSource="{Binding Path=Data.MyOptions, Source={StaticResource ProxyElement}" 
         SelectedItemBinding="{Binding Enum1, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource MyConverter}}"> 
</DataGridComboBoxColumn> 
+0

感謝您的快速答覆。當我嘗試這個時,我得到以下錯誤: System.Windows.Data錯誤:3:找不到提供DataContext的元素。 BindingExpression :(無路徑);的DataItem = NULL;目標元素是'FrameworkElement'(Name ='');目標屬性是'DataContext'(類型'對象') – uncletall

+0

我的壞......不能提到類應該擴展Freezable類..更新答案... Freezable用於綁定DataContext不被繼承的數據 – Nitin

+0

謝謝!測試它,現在它工作!還有很多要學習;) – uncletall

相關問題