C# 使用用户控件的表单赢得';t返回值

C# 使用用户控件的表单赢得';t返回值,c#,events,delegates,C#,Events,Delegates,我正在编写一个用户控件。我希望它在用户双击客户时返回客户编号。我似乎无法让它工作。显示用户控件,双击时,数据显示在messagebox中,但我似乎无法让它更新主窗体上的值 每当我尝试将返回值添加到FindCustomerControl\u ItemHasselected中时,我都会收到一个错误。它就像挂在用户控件中一样,我不能给它留一个返回值。到目前为止,我的情况如下: 在我的主窗口中: public partial class TestForm : Form { public Test

我正在编写一个用户控件。我希望它在用户双击客户时返回客户编号。我似乎无法让它工作。显示用户控件,双击时,数据显示在messagebox中,但我似乎无法让它更新主窗体上的值


每当我尝试将返回值添加到FindCustomerControl\u ItemHasselected中时,我都会收到一个错误。它就像挂在用户控件中一样,我不能给它留一个返回值。到目前为止,我的情况如下:

在我的主窗口中:

public partial class TestForm : Form
{
    public TestForm()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // one close button on the form
        Close();
    }


    private void ShowSelectFromListWidget()
    {
        // show the user control
        var uc = new FindCustomerControl();
        uc.ItemHasBeenSelected += uc_ItemHasBeenSelected;

        MakeUserControlPrimaryWindow(uc);
    }

    void uc_ItemHasBeenSelected(object sender,
                         FindCustomerControl.SelectedItemEventArgs e)
    {
        // once it has been selected, change a label on the screen to show the customer number
        var value = e.SelectedChoice;
        lblCustomer.Text = value;
    }

}
在我的用户控件中:

public partial class FindCustomerControl : UserControl
{
    public class SelectedItemEventArgs : EventArgs
    { public string SelectedChoice {  get; set; } }

    public event EventHandler<SelectedItemEventArgs> ItemHasBeenSelected;


    public FindCustomerControl()
         { InitializeComponent();}


    DataTable dt = new DataTable();
    public void btnFind_Click(object sender, EventArgs e)
    {   var dt = GetData();
        dataGridView1.DataSource = dt; }

    //Query database
    public DataTable GetData()
    {
        UtilitiesClass ru = new UtilitiesClass();
        string connectionString = ru.getConnectionString();

        DataTable dt = new DataTable();

        SqlConnection myConnection = new SqlConnection(connectionString);
        myConnection.Open();
        SqlCommand cmd = new SqlCommand("FindCustomer", myConnection);
        cmd.Parameters.AddWithValue("@customer", txtCustomer.Text.Trim());
        cmd.CommandType = CommandType.StoredProcedure;
        SqlDataAdapter ta = new SqlDataAdapter(cmd);
        ta.Fill(dt);
        myConnection.Close();
        return (dt);
    }

    private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
    {
        var handler = ItemHasBeenSelected;
        string choice = dataGridView1[0, e.RowIndex].Value.ToString();
        // this shows it 
        MessageBox.Show("Chosen: " + e.SelectedChoice);
        if (handler != null) handler(this, new SelectedItemEventArgs { SelectedChoice = choice });
        // I WOULD LIKE TO RETURN A VALUE HERE
    }


}
公共部分类FindCustomerControl:UserControl
{
公共类SelectedItemEventArgs:EventArgs
{public string SelectedChoice{get;set;}}
已选择公共事件事件处理程序项;
公共FindCustomerControl()
{InitializeComponent();}
DataTable dt=新的DataTable();
public void btnFind\u单击(对象发送者,事件参数e)
{var dt=GetData();
dataGridView1.DataSource=dt;}
//查询数据库
公共数据表GetData()
{
UtilitiesClass ru=新UtilitiesClass();
字符串connectionString=ru.getConnectionString();
DataTable dt=新的DataTable();
SqlConnection myConnection=新的SqlConnection(connectionString);
myConnection.Open();
SqlCommand cmd=newsqlcommand(“FindCustomer”,myConnection);
cmd.Parameters.AddWithValue(“@customer”,txtCustomer.Text.Trim());
cmd.CommandType=CommandType.storedProcess;
SqlDataAdapter ta=新的SqlDataAdapter(cmd);
ta.填充(dt);
myConnection.Close();
回报率(dt);
}
私有void dataGridView1\u CellDoubleClick(对象发送方,DataGridViewCellEventArgs e)
{
var handler=itemHasbeeSelected;
字符串选择=dataGridView1[0,e.RowIndex].Value.ToString();
//这说明了这一点
MessageBox.Show(“selected:+e.SelectedChoice”);
if(handler!=null)处理程序(这是新的SelectedItemEventArgs{SelectedChoice=choice});
//我想在这里返回一个值
}
}

这似乎已经足够普遍了,但是,尽管我花了数小时进行研究和调试,我还是无法找到解决方案。我知道uc.itemHasbeeSelected+=uc_itemHasbeeSelected;在TestForm中,似乎永远不会执行,因为我在那里放置了一个断点。

据我所知,我猜您可以使用应用程序当前资源,在那里您可以保存任何您想要的值-在UWP中,它是这样的:

Application.Current.Resources["Name"] = customerNumber
然后可以将此值强制转换为所需类型:

(int)Application.Current.Resources["Name"]
现在,您可以在任何地方使用此值


希望在任何方面都能有所帮助。

用户类没有问题。它很好用。问题是TestForm需要在没有FindCustomerControl的情况下启动,并在程序中实例化该控件。它将值返回到标签中或需要返回的任何位置。非常感谢Brad Rem和这篇文章:


}

“每当我尝试将返回值添加到FindCustomerControl\u Item已选中时,我都会收到一个错误。”?另外,如果我猜对了您尝试的内容,那么可能会给您一些想法。您说值显示在
消息框中,但值未显示在
TestForm.lblCustomer
文本框中,这意味着您的
TestForm.uc\u itemsbeenselected()
方法从未被调用。由于显示了消息框,
itemHasbeeSelected
事件显然按预期引发。在我看来,这就留下了两种可能性:您的
TestForm
没有订阅事件,或者您的
lblCustomer
实际上正在更新,但由于某些原因,标签文本不可见。如果没有可靠地再现问题的良好工具,仅凭您的问题就不可能知道问题是什么。要么改进问题,使其可以回答,要么自己进行更多的调试。请注意,您的代码显示订阅某个对象上的事件,但由于您没有显示
MakeUserControlPrimaryWindow()
,因此无法确认您已订阅正确对象上的事件。据我们所知,您有另一个实际接受用户输入的用户控件实例。这不是订阅了事件的测试表单吗?uc.ItemHasbeeSelected+=uc_ItemHasbeeSelected;另外,我取出了MakeUserControlPrimaryWindow(),因为它似乎没有任何区别,我试图使我的代码简洁。非常感谢您的帮助。这是一个好主意,但我会有很多用户,所以这次可能不适合我。不过,我知道我总有一天会用到它的。您可以始终为当前资源分配一个数组,该数组将包含所有客户,然后将其转换为一个arrayGood主意。我会用的。
 public partial class TestForm : Form
   {
     public TestForm()
    {
        InitializeComponent();
        ShowSelectFromListWidget();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Close();
    }


    private void ShowSelectFromListWidget()
    {
        var uc = new FindCustomerControl();
        uc.ItemHasBeenSelected += uc_ItemHasBeenSelected;
        this.MakeUserControlPrimaryWindow(uc);
    }

    void uc_ItemHasBeenSelected(object sender, FindCustomerControl.SelectedItemEventArgs e)
    {
        var value = e.SelectedChoice;
        lblCustomer.Text = value;
        lblMerchant.Focus();

        //ClosePrimaryUserControl();
    }

    private void MakeUserControlPrimaryWindow(UserControl uc)
    {
        // my example just puts in in a panel, but for you
        // put your special code here to handle your user control management 
        panel1.Controls.Add(uc);
    }


    private void ClosePrimaryUserControl()
    {
        // put your special code here to handle your user control management 
        panel1.Controls.Clear();
    }