2013-05-06 60 views
1

我有一個奇怪的錯誤與我的DataTemplatePersonDataTemplate」我用它作爲CellTemplateCellEditingTemplate。在我CellTemplate所有工作正常,但在我的CellEditingTemplate我獲得以下錯誤DataGrid上的BindingError 40 CellEditingTemplate

System.Windows.Data Error: 40 : BindingExpression path error: 'PersonId' property not found on 'object' ''DataRowView' (HashCode=59318978)'. BindingExpression:Path=PersonId; DataItem='DataRowView' (HashCode=59318978); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') 
System.Windows.Data Error: 40 : BindingExpression path error: 'PersonName' property not found on 'object' ''DataRowView' (HashCode=59318978)'. BindingExpression:Path=PersonName; DataItem='DataRowView' (HashCode=59318978); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') 

我的模板

<DataTemplate x:Key="PersonDataTemplate" DataType="Person"> 
     <StackPanel> 
      <TextBlock Background="LightBlue" Text="{Binding PersonId}"/> 
      <TextBlock Background="AliceBlue" Text="{Binding PersonName}"/> 
     </StackPanel> 
    </DataTemplate> 

,這裏是我的代碼

Person.cs其餘

public class Person 
    { 
     private int personId; 
     private string personName; 

     public int PersonId 
     { 
      get { return personId; } 
      set { personId = value; } 
     } 
     public string PersonName 
     { 
      get { return personName; } 
      set { personName = value; } 
     } 
    } 

個MainWindow.cs

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     simpleDataGrid.ItemsSource = LoadDataTable().AsDataView(); 
    } 

    /// <summary> 
    /// Here i place my PersonDataTemplate as CellTemplate and CellEditingTemplate 
    /// </summary> 
    private void simpleDataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
    { 
     if (e.PropertyType == typeof(Person)) 
     { 
      MyDataGridTemplateColumn col = new MyDataGridTemplateColumn(); 
      col.ColumnName = e.PropertyName; 
      col.CellTemplate = (DataTemplate)FindResource("PersonDataTemplate"); 
      col.CellEditingTemplate = (DataTemplate)FindResource("PersonDataTemplate"); 
      e.Column = col; 
      e.Column.Header = e.PropertyName; 
     } 
    } 

    /// <summary> 
    /// Here I create and fill my DataTable 
    /// </summary> 
    private DataTable LoadDataTable() 
    { 
     var _simpleDataTable = new DataTable(); 

     var person = new DataColumn("Person") { DataType = typeof(Person) }; 
     _simpleDataTable.Columns.Add(person); 

     var dr1 = _simpleDataTable.NewRow(); 
     dr1[0] = new Person { PersonId = 1, PersonName = "TONY" }; 
     _simpleDataTable.Rows.Add(dr1); 

     var dr2 = _simpleDataTable.NewRow(); 
     dr2[0] = new Person { PersonId = 2, PersonName = "MAL" }; 
     _simpleDataTable.Rows.Add(dr2); 

     _simpleDataTable.AcceptChanges(); 

     return _simpleDataTable; 
    } 

    private void simpleDataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) 
    { 
     // just to check the Values 
    } 
} 

public class MyDataGridTemplateColumn : DataGridTemplateColumn 
{ 
    public string ColumnName { get; set; } 

    protected override System.Windows.FrameworkElement GenerateElement(DataGridCell cell, object dataItem) 
    { 
     // The DataGridTemplateColumn uses ContentPresenter with your DataTemplate. 
     ContentPresenter cp = (ContentPresenter)base.GenerateElement(cell, dataItem); 
     // Reset the Binding to the specific column. The default binding is to the DataRowView. 
     BindingOperations.SetBinding(cp, ContentPresenter.ContentProperty, new Binding(this.ColumnName)); 
     return cp; 
    } 
} 

MainWindow.XAML

<Window x:Class="HowBindDataTableToDataGrid.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <!-- you for each Class one DataTemplate--> 
     <DataTemplate x:Key="PersonDataTemplate" DataType="Person"> 
      <StackPanel> 
       <TextBlock Background="LightBlue" Text="{Binding PersonId}"/> 
       <TextBlock Background="AliceBlue" Text="{Binding PersonName}"/> 
      </StackPanel> 
     </DataTemplate> 
    </Window.Resources> 
    <Grid> 
     <DataGrid Name="simpleDataGrid" AutoGeneratingColumn="simpleDataGrid_AutoGeneratingColumn" BeginningEdit="simpleDataGrid_BeginningEdit" /> 
    </Grid> 
</Window> 

特殊信息的

  • 我的ItemsSource是一個DataTable
  • MyDataGridTemplateColumn基於this答案(我也測試了,沒有運氣的其他解決方案)
  • 我還測試了單獨的DataTemplate我CellEditingTemplate沒有運氣

回答

1

您應該重寫GenerateEditingElement過,然後將生成的元素的內容,如您做GenerateElement方法:

public class MyDataGridTemplateColumn : DataGridTemplateColumn 
{ 
    public string ColumnName { get; set; } 

    protected override System.Windows.FrameworkElement GenerateElement(DataGridCell cell, object dataItem) 
    { 
     // The DataGridTemplateColumn uses ContentPresenter with your DataTemplate. 
     ContentPresenter cp = (ContentPresenter)base.GenerateElement(cell, dataItem); 

     // Reset the Binding to the specific column. The default binding is to the DataRowView. 
     BindingOperations.SetBinding(cp, ContentPresenter.ContentProperty, new Binding(this.ColumnName)); 
     return cp; 
    } 

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) 
    { 
     // The DataGridTemplateColumn uses ContentPresenter with your DataTemplate. 
     ContentPresenter cp = (ContentPresenter)base.GenerateEditingElement(cell, dataItem); 

     // Reset the Binding to the specific column. The default binding is to the DataRowView. 
     BindingOperations.SetBinding(cp, ContentPresenter.ContentProperty, new Binding(this.ColumnName)); 
     return cp; 
    } 

} 
+0

哇這很簡單:D – WiiMaxx 2013-05-06 10:34:49