2013-10-03 125 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

相关问题