2010-08-31 84 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> 
相關問題