2010-08-31 81 views
3

由于无法将值粘贴到DataGridTemplateColumn中。我发现了一些关于创建自己的从DataGridBoundColumn派生的列类的建议。下面的示例在不使用模板的情况下向该列添加DatePicker。如何将值设置为WPF中的自定义DataGridBound列

但是,此示例不允许我使用DatePicker手动设置值,我不知道为什么。我认为这是有约束力的东西。它会加载我最初绑定到它的日期值,因此它在一半的位置。

有趣的是,使用一些其他的辅助类,我可以粘贴日期以及这是origianl的目的。我只是不想破坏别的东西。 :-)

任何想法如何使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); 
    } 
} 

回答

1

的解决方案是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

我发现了一个更简单,更通用的解决方法。我没有为每个模板列创建自定义列,而是创建了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> 
相关问题