【问题标题】:Form Using User Control Won't Return Value使用用户控件的表单不会返回值
【发布时间】:2016-07-03 19:45:02
【问题描述】:

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

每当我尝试将返回值添加到 FindCustomerControl_ItemHasBeenSelected 中时,都会出现错误。就像它挂在用户控件中一样,我不能给它留下一个返回值。到目前为止,这就是我所拥有的:

在我的主窗口中:

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
    }


}

这似乎应该足够普遍,但是,尽管我进行了数小时的研究和调试,但我仍然无法提出解决方案。我知道 uc.ItemHasBeenSelected += uc_ItemHasBeenSelected;在 TestForm 中似乎永远不会被执行,因为我在那里放了一个断点。

【问题讨论】:

  • “每当我尝试将返回值添加到 FindCustomerControl_ItemHasBeenSelected 中时,都会出现错误。”。 Which error exactly do you get and how do you try to add it?另外,如果我猜对了你的尝试,那么this 可能会给你一些想法。
  • 你说值显示在MessageBox中,但值没有显示在TestForm.lblCustomer文本框中,这意味着你的TestForm.uc_ItemHasBeenSelected()方法永远不会被调用。由于显示了消息框,ItemHasBeenSelected 事件显然按预期引发。在我看来,这留下了两种可能性:您的 TestForm 没有订阅该事件,或者您的 lblCustomer 实际上正在更新,但由于某种原因标签文本不可见。
  • 如果没有一个好的minimal reproducible example 可以可靠地重现问题,仅凭您的问题就不可能知道问题所在。要么改进问题以使其可以回答,要么自己进行更多调试。请注意,您的代码显示订阅了 some 对象上的事件,但由于您没有显示 MakeUserControlPrimaryWindow(),因此无法确认您已订阅 正确 对象。据我们所知,您还有另一个实际接受用户输入的用户控件实例。
  • 这不是为测试表单订阅事件吗? uc.ItemHasBeenSelected += uc_ItemHasBeenSelected;另外,我取出了 MakeUserControlPrimaryWindow(),因为它似乎没有任何区别,而且我试图让我的代码简洁。

标签: c# events delegates


【解决方案1】:

据我了解,我猜您可以使用应用程序当前资源,您可以在其中保存任何您希望的值 - 在 UWP 中是这样的:

Application.Current.Resources["Name"] = customerNumber

然后您可以将此值转换为所需的类型:

(int)Application.Current.Resources["Name"]

现在您可以在任何地方使用此值。

希望大于帮助。

【讨论】:

  • 非常感谢您的帮助。这是一个好主意,但我会有很多用户,所以这次可能对我不起作用。不过,我知道我会在一段时间内使用它。
  • 您可以随时为当前资源分配一个数组,其中将包含所有客户,然后将其转换为数组
  • 好主意。我会用的。
【解决方案2】:

用户类没有任何问题。它工作正常。问题是 TestForm 需要在没有 FindCustomerControl 的情况下启动,并在程序中实例化控件。它将值返回到标签或它需要的任何其他地方。非常感谢 Brad Rem 和这篇文章:Return value from usercontrol after user action

 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();
    }

}

【讨论】:

    猜你喜欢
    • 2012-04-15
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 1970-01-01
    相关资源
    最近更新 更多