2013-10-03 3 views
0

Я пытаюсь использовать перечисление в Datagrid. Позвольте мне показать вам два способа, которыми он может работать. Во-первых, я создаю ComboBox внутри DataGrid, DataContext.MyOptions возвращает список строк для всех значений enum.Свойство Bind 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 от родителя, и они не могут ссылаться на Ancestor.

Строки и ячейки DataGrid, с другой стороны, подпадают под визуальную форму и, следовательно, могут найти предка и наследовать 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 = ''); target is 'DataContext' (type 'Object') – uncletall

+0

my bad..нельзя сказать, что класс должен расширять класс Freezable .. обновленный ответ ... Freezable используются для привязки данных, где DataContext не унаследован – Nitin

+0

Спасибо ! Протестировал его сейчас, и он работает! Еще многое узнать;) – uncletall

Смежные вопросы