DataGrid cellleditingtemplate绑定错误40

本文关键字:错误 绑定 cellleditingtemplate DataGrid | 更新日期: 2023-09-27 18:12:11

我有一个奇怪的bug与我的DataTemplate " PersonDataTemplate "我用它作为CellTemplateCellEditingTemplate。在我的CellTemplate上所有工作正常,但在我的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;
    }
}

主窗口。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>

特殊信息的

  • My ItemsSource is a DataTable
  • 我的MyDataGridTemplateColumn基于这个答案(我也测试了其他解决方案没有运气)
  • 我还为我的CellEditingTemplate测试了一个单独的DataTemplate,没有运气

DataGrid cellleditingtemplate绑定错误40

您也应该重写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;
    }
}