[摘要]
我的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是私有的...由于受到保护,因此无法这样做 级别...
让我们假设我不想将这些文本框的保护级别更改为公开。
答案 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)
方法。在这种情况下,表单将显示为模式对话框。
我正在使用此公共方法制作两个示例:
InvoiceForm
控件中设置的所有值。这可能是通过这些检查的首选方法
值,因为它可以更轻松地扩展并在不同的上下文中重复使用。 带有类参数的公共方法:
请注意,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
。