获取 SfDataGrid 中特定单元格值的技术

Techniques for getting the value of a specific cell in an SfDataGrid

我正在创建一个非常简单的库存控制应用程序,旨在供一个人使用。我想我会喜欢并使用 Syncfusion 的一些控件以获得更好的外观 UI。不幸的是,SfDataGrid 似乎不包含任何与 DataGridView 相同的功能。我在使用他们提供的获取单元格值的技术时遇到了问题。以下是我从他们的文档中获得的片段:

private static string GetCellValue(SfDataGrid dGrid, int rowIndex, int columnIndex)
    {
        string cellValue;
        if (columnIndex < 0)
            return string.Empty;
        var mappingName = dGrid.Columns[columnIndex].MappingName;
        var recordIndex = dGrid.TableControl.ResolveToRecordIndex(rowIndex);
        if (recordIndex < 0)
            return string.Empty;
        if (dGrid.View.TopLevelGroup != null)
        {
            var record = dGrid.View.TopLevelGroup.DisplayElements[recordIndex];
            if (!record.IsRecords)
                return string.Empty;
            var data = (record as RecordEntry).Data;
            cellValue = (data.GetType().GetProperty(mappingName).GetValue(data, null).ToString());
        }
        else
        {
            var record1 = dGrid.View.Records.GetItemAt(recordIndex);
            cellValue = (record1.GetType().GetProperty(mappingName).GetValue(record1, null).ToString());
        }

        return cellValue;
    }

在 cellValue 赋值中调用 GetProperty(mappingName) 之前,这一切都很好。我想获取相关项目的系统 ID,因为我的数据库将使用它来删除特定项目。此方法将获取我需要的列的映射名称,但它不会从单元格中提取数据,我也不知道为什么。下面是 Autos window 的捕获,以显示与函数相关的变量: Auto Tab displaying related variables, such as cellValue and mappingName. It clearly demonstrates cellValue returning null when it should contain a string of an integer. cellValue 应该包含一个整数字符串,然后我将基于我的数据库删除指定的项目。我尝试获取列的集合并循环遍历它们,直到找到匹配的映射名称,然后才硬连接列索引。据我所知,列和行索引不是问题。系统 ID 列的索引为 6,行索引通过使用 e.DataRow.RowIndex 的单击事件参数访问。下面这个函数调用的是GetCellValue函数,可能对判断这个问题有一定的用处。

private void inventoryGridView_CellClick(object sender, Syncfusion.WinForms.DataGrid.Events.CellClickEventArgs e)
    {
        if (e.DataColumn.ColumnIndex == 0) 
        {
            return;
        }
        if (e.DataColumn.ColumnIndex == 7) 
        {
            if (MessageBox.Show("Are you sure you want to delete this item?", "Confirmation", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes) 
            {
                //TODO: Make delete buttons work
                //this code below calls a function that may not be working properly
                // Get the row index value        
                var rowIndex = e.DataRow.RowIndex;
                //Get the column index value
                var columnIndex = 6;
                //Get the cell value            
                var cellValue = GetCellValue(inventoryGridView, rowIndex, columnIndex);
                MessageBox.Show("Cell value \t:  " + cellValue, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            return;
        }
    }

inventoryGridView 是我的 SfDataGrid,而列索引 7 是一列删除按钮,应该删除它们共享一行的项目。如果需要更多信息,请告诉我,我会提供。我确实找到了 this sample on GitHub, but it is identical to the documentation on Syncfusion's website. I also remember reading a Whosebug post that was identical to this Syncfusion forum post, reply and everything. 虽然这也没有帮助,因为它似乎暗示 GetCellValue 应该已经是一个成员方法,但至少在我的情况下不是这样。

最后,这是我的 SfDataGrid 的图片,所以你们都可以看到完整的图片:SfDataGrid inventoryGridView sample picture.

所以,对于那些和我一样掉进深渊的人,这里有一些答案: Syncfusion 批准的方法在他们的示例项目之外不起作用(至少对我而言,似乎还有很多其他人)。 GetItemAt() 函数实际上 returns 一个 DataRowView,而不是您要查找的项目对象。要实际从特定单元格中提取值,您需要替换这些代码行:

var record1 = dGrid.View.Records.GetItemAt(recordIndex);
cellValue = (record1.GetType().GetProperty(mappingName).GetValue(record1, null).ToString());

用这行代码:

DataRowView record1 = dGrid.View.Records.GetItemAt(recordIndex) as DataRowView;
cellValue = (record1[mappingName].ToString()); 

我不是 100% 确定此修复程序为何对我有效,但在我弄清楚返回的内容后,DataRowView 上的 Microsoft 文档指导我找到了我需要的内容。在这里,我使用 DataRowView.Item[] 属性 来获得我需要的东西。

我希望这可以帮助任何人发现自己处于我的情况,这里是我上面提到的 属性 文档的 link:DataRowView.Item[]

根据提供的信息,报告的问题是由于在 SfDataGrid 中获取 DataRow 的类型转换不匹配所致。

您可以通过将 record1data 对象类型转换为 DataRowView 来解决所报告的问题像下面提到的代码片段,

private static string GetCellValue(SfDataGrid dGrid, int rowIndex, int columnIndex)
{
        
        string cellValue;
        if (columnIndex < 0)
            return string.Empty;
        var mappingName = dGrid.Columns[columnIndex].MappingName;
        var recordIndex = dGrid.TableControl.ResolveToRecordIndex(rowIndex);
        if (recordIndex < 0)
            return string.Empty;
        if (dGrid.View.TopLevelGroup != null)
        {
            var record = dGrid.View.TopLevelGroup.DisplayElements[recordIndex];
            if (!record.IsRecords)
                return string.Empty;
            var data = (record as RecordEntry).Data;
            //below case using for ObservableCollection binded in dataGrid
            //cellValue = (data.GetType().GetProperty(mappingName).GetValue(data, null).ToString());

            //below case using for DataTable Collection binded in dataGrid 
            cellValue = (data as DataRowView).Row[mappingName].ToString();
        }
        else
        {
            var record1 = dGrid.View.Records.GetItemAt(recordIndex);

            //below case using for ObservableCollection binded in dataGrid  
            //cellValue = (record1.GetType().GetProperty(mappingName).GetValue(record1, null).ToString());

            //below case using for DataTable Collection binded in dataGrid 
            cellValue = (record1 as DataRowView).Row[mappingName].ToString();
        }

        return cellValue;
    }

示例 Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/Sample-2052934720