我正在尝试在Datagrid中使用枚举。让我告诉你两种可行的方法。 首先,我在DataGrid中创建一个ComboBox,DataContext.MyOptions返回所有枚举值的字符串列表。
<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')
答案 0 :(得分: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>