如何将文本从一种形式的数据网格视图传输到另一种形式的私人文本框

时间:2018-11-25 21:03:07

标签: c# class constructor properties private

[摘要] 我的C#程序中有一个Invoice form和几个私有TextBoxes。当用户更改这些文本框的文本时,将显示search form。我想将某些值从search form中的dataGridView(链接到我的数据库)传输到Invoice form中的那些TextBox(例如,当我按Enter键时)。

[说明] 在我的发票表格中,我有商品代码文本框和商品名称文本框。当用户更改这些文本框的文本时,将出现搜索表单,并且输入的文本将被传输到searchform的文本框中。搜索表单只有一个文本框和一个datagridview。在搜索表单的文本框中输入内容后,datagridview将搜索并在datagridview中显示结果。 datagridview具有作为发票表单文本框的重复列。现在,我要设法做到这一点:当我在searchform上输入内容时,datagridview当前行的信息将被转移到Invoice表单中的可重复文本框中。商品代码列到商品代码文本框,商品名称列到商品名称文本框。

我可以用以下代码说明这一点: (我知道如何在datagridview中获取所选行的值,我的问题只是标题...)

if (e.KeyCode == Keys.Enter)
{
    SqlCommand sqlcmd = new SqlCommand("SELECT ID FROM X WHERE ID=" +
                        dataGridView1.CurrentRow.Cells[0].Value + "", sqlcon);
    SqlDataReader sqldr = sqlcmd.ExecuteReader();
    while (sqldr.Read())
    {
        InvoiceForm.CodeTextBox = sqldr[codecolumn].Tostring
        InvoiceForm.NameTextBox = sqldr[Namecolumn].Tostring
        InvoiceForm.BlahTextBox = sqldr[Blahcolumn].Tostring                               
    }
}

我尝试了上面的代码,但是有问题:

  

codeTextBox是私有的...由于受到保护,因此无法这样做   级别...

让我们假设我不想将这些文本框的保护级别更改为公开。

2 个答案:

答案 0 :(得分:2)

没有实现接口,有两种简单的方法可以从另一个类引用现有的Form类。

在被调用方的构造函数中传递调用方类(this)的引用:

Form2 form2 = new Form2(this);
form2.Show();

使用被叫方(Form2)的Owner属性。使用Show(Owner)ShowDialog(Owner)方法设置所有者。 this是调用方的实例:

Form2 form2 = new Form2();
form2.Show(this);

您还可以在被叫方(Form2)中拥有一个公共属性,用于设置当前的主叫方(this):

Form2 form2 = new Form2();
form2.MyCaller = this;
form2.Show();

几乎没有用,因为前两种方法已经使用标准功能实现了相同的结果。当然,还有其他方法,但是在这种情况下几乎是矫kill过正。

在这里,我正在使用Owner属性访问实例化Form Form类的Search类的实例。该示例使用呼叫者类(您的InvoiceForm)的公共方法,被呼叫者(您的Search表单)使用该方法来回传用户选择的值。
使用Form.Show(this)还意味着所显示的表单将被 parented (不要与Parent属性混淆),并且与显示它的表单保持一致。它。
如果您的情况更可取,则也可以使用ShowDialog(this)方法。在这种情况下,表单将显示为模式对话框。

我正在使用此公共方法制作两个示例:

  1. 带有类参数的公共方法,该方法包含可以在InvoiceForm控件中设置的所有值。这可能是通过这些检查的首选方法 值,因为它可以更轻松地扩展并在不同的上下文中重复使用。
  2. 带有字符串参数的公共方法,对应于 要设置的TextBoxes值

带有类参数的公共方法
请注意,this.Owner is InvoiceForm frm用于标识当前的Owner
UpdateMyControls类是用于传输特定值的容器。如果所有者是其他所有者,则SearchForm的行为可能会有所不同。
这在某种程度上得到了简化,但是您可以使用此选择将SearchForm与不同的调用方重复使用,每个Owner的结果都不同。

注意:用于传递值/引用的类可以在SearchForm的构造函数中传递,可能使用众所周知的合同(接口)来定义。值及其类型。在这里无法描述,但您应该考虑探索这种可能性。

public partial class InvoiceForm : Form
{
    public class UpdateMyControls 
    {
        public string CodeText { get; set; }
        public string NameText { get; set; }
        public string BlahText { get; set; }
    }

    private void btnSearch_Click(object sender, EventArgs e)
    {
        SearchForm searcher = new SearchForm();
        searcher.Show(this);
    }

    public void UpdateControls(UpdateMyControls allValues)
    {
        this.CodeTextBox.Text = allValues.CodeText;
        this.NameTextBox.Text = allValues.NameText;
        this.BlahTextBox.Text = allValues.BlahText;
    }
}

public partial class SearchForm : Form
{
    private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Enter)
        {
            if (this.Owner is InvoiceForm frm)
            {
                InvoiceForm.UpdateMyControls updateClass = new InvoiceForm.UpdateMyControls();

                updateClass.CodeText = sqldr[codecolumn].ToString();
                updateClass.NameText = sqldr[Namecolumn].ToString();
                updateClass.BlahText = sqldr[Blahcolumn].ToString();
                frm.UpdateControls(updateClass);
                this.Close();
            }
        }
    }
}

具有多个参数的公开方法

public partial class InvoiceForm : Form
{
    private void btnSearch_Click(object sender, EventArgs e)
    {
        SearchForm searcher = new SearchForm();
        searcher.Show(this);
    }

    public void UpdateControls(string Code, string Name, string Blah)
    {
        this.CodeTextBox.Text = Code;
        this.NameTextBox.Text = Name;
        this.BlahTextBox.Text = Blah;
    }
}

public partial class SearchForm : Form
{
    private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Enter)
        {
            string CodeValue = sqldr[codecolumn].ToString()
            string NameValue = sqldr[Namecolumn].Tostring
            string BlahValue = sqldr[Blahcolumn].Tostring 

            if (this.Owner is InvoiceForm frm)
            {
                frm.UpdateControls(CodeValue, NameValue, BlahValue);
                this.Close();
            }
        }
    }
}

答案 1 :(得分:0)

有效地,您应该避免直接访问表单中的控件的属性,因为它会使调用者代码直接依赖于表单的UI。例如,如果您想更改组合框或第三方文本框的文本框,则可能必须在多个位置进行更改。

在简单的情况下,如果属性本质上是独立的,我通常会在类中添加属性,以向调用者隐藏实现细节。

public string Code
{
    get { return CodeTextBox.Text; }
    set { CodeTextBox.Text = value; }
}

如果控件相关,则最好使用函数

public void SetData(string code, string name, string blah)
{
    CodeTextBox.Text = code;
    NameTextBox.Text = name;
    BlahTextBox.Text = blah;
}

如果这样做,则可以保留属性,然后将其设置为只读,以便在需要时使用该功能。

但是,如果您从数据库中重新加载数据,则可以考虑将代码移至InvoiceForm并具有类似于以下功能:

void LoadFromDatabase(int itemId)
{
    var sqlcmd = new SqlCommand("SELECT ID FROM X WHERE ID=" +
                        itemId.ToString(), sqlcon);
    var sqldr = sqlcmd.ExecuteReader();
    if (sqldr.Read())
    {
        InvoiceForm.CodeTextBox = sqldr[codecolumn].Tostring();
        InvoiceForm.NameTextBox = sqldr[Namecolumn].Tostring();
        InvoiceForm.BlahTextBox = sqldr[Blahcolumn].Tostring();                               
    }
}

顺便说一句,请注意我已将while循环替换为if条件。显然,查询应返回单个项目,否则将意味着数据库包含重复值。如果数据是伪造的,为什么还要将最后退回的物品比第一个退货?

();通话之后,我还添加了丢失的ToString