DataGridTemplateColumn получить значение ячейки - PullRequest
1 голос
/ 20 декабря 2009

Я использую WPF DataGrid из набора инструментов WPF.

Я добавил шаблонный столбец к своему DataGrid, в каждой ячейке которого есть CheckBox. Теперь, как мне получить доступ к значениям в этих ячейках?

Мои другие столбцы в DataGrid взяты из DataSet. Я могу получить к ним доступ, но не могу получить значения DataGridTemplateColumn, которые я добавил к DataGrid.

У кого-нибудь есть идеи?

1 Ответ

3 голосов
/ 21 декабря 2009

теперь вы вытаскиваете вещи из визуального дерева. и это тяжелая работа, вы не можете найти привязку, потому что она скрыта в шаблоне ячейки. что я сделал, так это добавил свой собственный столбец для такого рода вещей, этот столбец наследуется от DataGridBoundColumn, что означает, что он имеет привязку, как и все остальные: я просто использую прямую привязку. мне не нужно устанавливать шаблон ячейки, я могу просто использовать DataTemplate, который мне нравится больше.

   public class DataGridReadOnlyObjectDisplayColumn : DataGridBoundColumn {

      public DataGridReadOnlyObjectDisplayColumn() {
         //set as read only,
         this.IsReadOnly = true;
      }


      /// <summary>
      /// Gets and Sets the Cell Template for this column
      /// </summary>
      public DataTemplate CellTemplate {
         get { return (DataTemplate)GetValue(CellTemplateProperty); }
         set { SetValue(CellTemplateProperty, value); }
      }

      // Using a DependencyProperty as the backing store for CellTemplate.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty CellTemplateProperty =
          DependencyProperty.Register("CellTemplate", typeof(DataTemplate), typeof(DataGridReadOnlyObjectDisplayColumn), new UIPropertyMetadata(null));



      protected override System.Windows.FrameworkElement GenerateElement(DataGridCell cell, object dataItem) {
         //create the simple field text block
         ContentControl contentControl = new ContentControl();

         contentControl.Focusable = false;

         //if we have a cell template use it
         if (this.CellTemplate != null) {
            contentControl.SetValue(ContentControl.ContentTemplateProperty, this.CellTemplate);
         }

         //set the binding
         ApplyBinding(contentControl, ContentPresenter.ContentProperty);

         //return the text block
         return contentControl;
      }

      /// <summary>
      ///     Assigns the Binding to the desired property on the target object.
      /// </summary>
      internal void ApplyBinding(DependencyObject target, DependencyProperty property) {
         BindingBase binding = Binding;

         if (binding != null) {
            BindingOperations.SetBinding(target, property, binding);
         }
         else {
            BindingOperations.ClearBinding(target, property);
         }
      }

      protected override System.Windows.FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) {
         //item never goes into edit mode it is a read only column
         return GenerateElement(cell, dataItem);
      }
   }

Теперь, если вы можете добраться до столбца, вы можете получить привязку к столбцу. если вы можете добраться до ячейки, то вы можете найти элемент данных (данные строки). то, что я делаю, это следую за связыванием, чтобы получить значение ячейки. это действительно неэффективно, и это взломать. но это работает. чтобы следовать привязке, я использую это.

 private Object GetCellValue(Binding columnBinding, object dataSource) {

     Object valueField = null;

     if (columnBinding != null) {
        BindingEvaluator bindingEvaluator = new BindingEvaluator();

        //copy the binding
        Binding binding = new Binding();
        binding.Path = columnBinding.Path;
        binding.Source = dataSource;

        //apply the binding
        BindingOperations.SetBinding(bindingEvaluator, BindingEvaluator.BindingValueProperty, binding);

        //get the current cell item
        valueField = bindingEvaluator.BindingValue as IValueField;
     }

     return valueField;
  }

и последний кусок - вспомогательный класс с именем BindingEvaluator, у которого есть один dp, который я использую для отслеживания привязки

   public class BindingEvaluator : DependencyObject {

      /// <summary>
      /// Gets and Sets the binding value
      /// </summary>
      public Object BindingValue {
         get { return (Object)GetValue(BindingValueProperty); }
         set { SetValue(BindingValueProperty, value); }
      }

      // Using a DependencyProperty as the backing store for BindingValue.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty BindingValueProperty =
          DependencyProperty.Register("BindingValue", typeof(Object), typeof(BindingEvaluator), new UIPropertyMetadata(null));
   }

и я называю это так:

 var valueField = this.GetCellValue(column.Binding as Binding, datagrid.CurrentCell.Item);
...