Как установить значения в пользовательский столбец DataGridBound в WPF - PullRequest
3 голосов
/ 31 августа 2010

Поскольку невозможно вставить значения в DataGridTemplateColumn.Я нашел несколько предложений по созданию моего собственного класса столбца, производного от DataGridBoundColumn.Пример ниже добавляет DatePicker в столбец без использования шаблона.

Однако этот пример не позволяет мне вручную устанавливать значение с помощью DatePicker, и я не уверен, почему.Я думаю, что есть что-то с привязкой.Он загрузит значения даты, которые я изначально привязал к нему, так что он на полпути.

Интересно, что с помощью некоторых других вспомогательных классов я также могу вставлять даты, что и было целью оригинала.Я просто не хотел ничего ломать.: -)

Есть идеи, как сделать так, чтобы выбранное значение указателя даты связывалось правильно?

class MyDateColumn : DataGridBoundColumn 
{
    public string DateFormat { get; set; }
    protected override void CancelCellEdit(FrameworkElement editingElement, object uneditedValue)
    {
        DatePicker dp = editingElement as DatePicker;
        if (dp != null)
        {
            dp.SelectedDate = DateTime.Parse(uneditedValue.ToString());
        }
    }
    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
    {
        DatePicker dp = new DatePicker();
        Binding b = new Binding();
        Binding bb = this.Binding as Binding;
        b.Path = bb.Path;
        b.Source = DatePicker.SelectedDateProperty;
        if (DateFormat != null)
        {
            DateTimeConverter dtc = new DateTimeConverter();
            b.Converter = dtc;
            b.ConverterParameter = DateFormat;
        }
        dp.SetBinding(DatePicker.SelectedDateProperty, this.Binding);

        return dp;
    }

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
        TextBlock txt = new TextBlock();
        Binding b = new Binding();
        Binding bb = this.Binding as Binding;
        b.Path = bb.Path;
        b.Source = cell.DataContext;

        if (DateFormat != null)
        {
            DateTimeConverter dtc = new DateTimeConverter();
            b.Converter = dtc;
            b.ConverterParameter = DateFormat;
        }
        txt.SetBinding(TextBlock.TextProperty, this.Binding);
        return txt;
    }

    protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs)
    {
        DatePicker dp = editingElement as DatePicker;
        if (dp != null)
        {
            DateTime? dt = dp.SelectedDate;
            if (dt.HasValue)
                return dt.Value;
        }
        return DateTime.Today;
    }

    protected override bool CommitCellEdit(FrameworkElement editingElement)
    {
        DatePicker dp = editingElement as DatePicker;
        dp.SelectedDate = DateTime.Today.AddYears(1);

        return true;
        //return base.CommitCellEdit(editingElement);
    }
}

Ответы [ 2 ]

1 голос
/ 01 сентября 2010

Решение представляет собой модификацию CommitCellEdit () ...

    protected override bool CommitCellEdit(FrameworkElement editingElement)
    {
        DatePicker dp = editingElement as DatePicker;
        DateTime dt;
        try
        {
            dt = Convert.ToDateTime(dp.Text);
            dp.SelectedDate = dt;
        }
        catch (FormatException)
        {
            dp.Text = String.Empty;
        }


        BindingExpression binding = editingElement.GetBindingExpression(DatePicker.SelectedDateProperty);
        if (binding != null)
            binding.UpdateSource();
        return true;
        //return base.CommitCellEdit(editingElement);
    }

Исходный код и справка можно получить по следующей ссылке ...

http://leeontech.wordpress.com/2009/01/21/creating-datagriddatecolumn-for-datagrid/#comment-1033

Спасибо за создание образца и помощь Ли!

0 голосов
/ 26 октября 2011

Я нашел более простой и общий способ ее решения.Вместо создания настраиваемого столбца для каждого столбца шаблона я создал 1 настраиваемый столбец, который наследуется от DataGridTemplateColumn.Это решит все ваши шаблоны, которые вы хотите иметь.Пользовательский столбец имеет дополнительное свойство BindingPath, в котором вы указываете, какое свойство в связанном объекте вы хотите обновить, вставив данные.Очевидно, что связанный объект должен реализовывать интерфейс INotifyPropertyChanged.После обновления источника ваши элементы управления будут обновляться автоматически.

Вот код пользовательской колонки:

using System.Reflection;
using Microsoft.Windows.Controls;

namespace Bartosz.Wojtowicz.Wpf
{
    public class PastableDataGridTemplateColumn : DataGridTemplateColumn
    {
        public string BindingPath { get; set; }

        public override void OnPastingCellClipboardContent(object item, object cellContent)
        {
            if (item != null)
            {
                PropertyInfo propertyInfo = item.GetType().GetProperty(BindingPath);
                if (propertyInfo != null)
                {
                    propertyInfo.SetValue(item, cellContent, null);
                }
            }
        }
    }
}

А вот как вы используете его в xaml:

 <local:PastableDataGridTemplateColumn Header="Value" BindingPath="ValueView" ClipboardContentBinding="{Binding ValueView}" >
  <local:PastableDataGridTemplateColumn.CellTemplate >
    <DataTemplate>
      <!-- your template ... -->
    </DataTemplate>
  </local:PastableDataGridTemplateColumn.CellTemplate>
  <local:PastableDataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
      <!-- your template ... -->
    </DataTemplate>
  </local:PastableDataGridTemplateColumn.CellEditingTemplate>
</local:PastableDataGridTemplateColumn>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...