从窗体中的UserControl,我如何访问父窗体的DataGridView ?

本文关键字:窗体 访问 DataGridView UserControl 何访问 | 更新日期: 2023-09-27 18:02:21

问题:我试图从用户控件(AttachmentOptions.cs)访问我的Windows窗体(ClientSearch.cs)的DataGridView,以便我可以使用它检索的数据。

Background: ClientSearch.cs是一个windows窗体,可以在我的Outlook插件上的电子邮件上显示。它允许用户搜索客户端(以及他们在系统上各自的文件夹),以便将电子邮件或附件归档到其中。AttachmentOptions.cs是为电子邮件中的每个附件生成的用户控制,以便每个附件将具有相同的归档选项组。


我已经采取了一些步骤来解决这个问题,但我还是遇到了更多的问题。如果我把情况弄得更糟,我将展示我的步骤: 原始:

var txtClient = parentItem.Controls.Find("txtClient", true); //This works as I want
var dgvClients = parentItem.Controls.Find("dgvClients", true);
DataGridView test = dgvClients; //Error appears on this line
strClientName = test.CurrentRow.Cells[0].Value.ToString();

错误:

错误1无法隐式转换类型"System.Windows.Forms"。Control[]' to 'System.Windows.Forms.DataGridView'


修复尝试1:

var txtClient = parentItem.Controls.Find("txtClient", true);
var dgvClients = (DataGridView)parentItem.Controls.Find("dgvClients", true).Cast<DataGridView>; //Error on this line
DataGridView test = dgvClients;
strClientName = test.CurrentRow.Cells[0].Value.ToString();
错误:

错误20无法将方法组"Cast"转换为非委托类型"System.Windows.Forms.DataGridView"。您是否打算调用该方法?


修复尝试2:

var dataGridInfo = parentItem.Controls.Find("dgvClients", true);
var dgvClients = (DataGridView)dataGridInfo; //Error is here
DataGridView test = dgvClients;
strClientName = test.CurrentRow.Cells[0].Value.ToString();
错误:

错误20无法转换类型"System.Windows.Forms"。Control[]' to 'System.Windows.Forms.DataGridView'


修复尝试3:
var dataGridInfo = parentItem.Controls.Find("dgvClients", true);
DataGridView dgvClients = dataGridInfo.Cast<DataGridView>; //Error is here
DataGridView test = dgvClients;
strClientName = test.CurrentRow.Cells[0].Value.ToString();
错误:

错误20无法将方法组"Cast"转换为非委托类型"System.Windows.Forms.DataGridView"。您是否打算调用该方法?


修复尝试4:

        //var dgvClients = parentItem.Controls.Find("dgvClients", true);
        var dataGridInfo = parentItem.Controls.Find("dgvClients", true);
        DataGridView dgvClients;
        dgvClients = (DataGridView)dataGridInfo; //Error is here
        DataGridView test = dgvClients;
        strClientName = test.CurrentRow.Cells[0].Value.ToString();
错误:

错误20无法转换类型"System.Windows.Forms"。Control[]' to 'System.Windows.Forms.DataGridView'


我觉得我在兜圈子,恶化我的代码,因为我去(因此我展示了以前的版本),试图与DataGridView交谈。似乎c#不喜欢将这两种类型转换在一起,所以有没有另一种方法来引用DataGridView对象?

作为参考,parentItem引用先前声明的ClientSearch,这适用于与ClientSearch.cs进行文本框之类的对话。

提前感谢您的时间和帮助

从窗体中的UserControl,我如何访问父窗体的DataGridView ?

错误就在那里,就在你眼前。

返回到原始代码。您正在从Controls.Find()返回一个数组,并试图将其视为单个对象。假设你知道数组中只有一个元素,你可能想要数组中的第一项。

var txtClient = parentItem.Controls.Find("txtClient", true);
var dgvClients = parentItem.Controls.Find("dgvClients", true);
DataGridView test = dgvClients[0] as DataGridView;
strClientName = test.CurrentRow.Cells[0].Value.ToString();

UserControl的父窗体中按名称查找控件确实是一个坏主意。

相反,您应该为UserControl创建一个DataGridView类型的属性,并使用代码或设计器分配它,并在UserControl中使用它。

public DataGridView ClientsGrid { get; set; }

不依赖于命名约定,而是依赖于开发人员的选择。

你有很多问题,让我们来解决它们:

  1. Find返回控件数组:

要解决这个问题,您需要从中取出第一项:

var dgvClients = parentItem.Controls.Find("dgvClients", true)
                                    .FirstOrDefault() as DataGridView;
  • Cast是一个方法
  • 调用方法时,需要使用括号():

    .Cast<DataGridView>();