3

本质上,我需要与 Form.ShowDialog() 提供的相同的东西,但需要一个 UserControl。

在 winform 中,我加载了一个 UserControl,它应该允许用户从列表中选择一个项目,并将其返回给调用者。

例如:

var item = myUserControl.SelectItem();

显然,从控件的方法返回非常简单。但是我怎样才能让它等到用户使用控件执行所需的操作?

我可以订阅控件的一个事件,但是这个路径并不理想。

简而言之,我希望 UserControl 的方法在用户单击其上的特定按钮后返回。

4

3 回答 3

5

简单地说,UserControl 实际上只是一个自定义控件,就像您在 WinFrom 上放置 aTextBox或 aListBox一样,您将 UserControl 放置在表单上。

像对待任何其他控件一样对待您的 UserControl,例如TextBoxor ListBox

因此,就像您从 a TextBoxthroughTextBox.Text或 the SelectedValueorSelectedItem从 a获取值一样ListBox,您将从 UserControl 调用一个方法以返回 SelectedItem。

通常,当单击确定按钮或关闭表单时,在您的代码中,您将通过每个表单的控件获取它们的值。大概,您会进行一些验证以确保也输入了正确的值。

因此,当您的表单被接受时,您将调用 UserControl 的方法来获取所选项目。您无需订阅事件即可等待该事件发生。再次,就像对待普通人一样对待它ListBox

编辑:

现在更多地了解您的问题的性质,这是我的回答:

假设您有一个如下所示的 UserControl:

SelectFromListUserControl

在后面的代码中,您将不得不设置一个事件来监视用户控件内单击“确定”按钮的时间。此事件还将通知订阅者用户在您的列表中选择的选项是什么:

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

    public event EventHandler<SelectedItemEventArgs> ItemHasBeenSelected;

    public SelectFromListUserControl()
    {
        InitializeComponent();
    }

    private void btnOK_Click(object sender, EventArgs e)
    {
        var handler = ItemHasBeenSelected;
        if (handler != null)
        {
            handler(this, new SelectedItemEventArgs 
                { SelectedChoice = listBox1.SelectedItem.ToString() });
        }
    }
}

在您的主窗体上,您将具有类似于以下的代码模式。

  1. 应该有一个例程来创建或使这个特殊的用户控件可见。
  2. 它将挂钩用户控件中的事件,以便通知主窗体。
  3. 它将绘制用户控件。
  4. 事件处理程序将检索在用户控件中选择的值,然后清除用户控件和/或调出另一个用户控件。

    private void ShowSelectFromListWidget()
    {
        var uc = new SelectFromListUserControl();
        uc.ItemHasBeenSelected += uc_ItemHasBeenSelected;
    
        MakeUserControlPrimaryWindow(uc);
    }
    
    void uc_ItemHasBeenSelected(object sender, 
                         SelectFromListUserControl.SelectedItemEventArgs e)
    {
        var value = e.SelectedChoice;
    
        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();
    }
    
于 2013-06-27T18:28:11.027 回答
0

将其嵌入表单并以模态方式调用表单(ShowDialog)?

于 2013-06-27T18:22:40.607 回答
0

但是我怎样才能让它等到用户使用控件执行所需的操作?

问题更多是关于如何等待用户选择项目并单击“确定”按钮而不阻塞整个用户界面。

答案很简单:Async/Await 功能。

private readonly SelectCompletionSource as new TaskCompletionSource(of ResultType)

public async function SelectItemAsync() as ResultType

    me.Visible = true

    return await SelectComplectionSource.Task
end function

public function OK() as boolean

    me.Visible = false

    dim Result = me.SelectedItem

    SelectComplectionSource.
        SetResult(Result)
end function

接到一个Item电话

dim Item = await UserControl.SelectItemAsync

UserControl在不阻塞用户界面的情况下向用户显示。选择任务开始但暂停,直到结果准备好。

通过单击确定按钮,用户调用OK查询所选项目并使选择任务进入完成状态的功能。

于 2017-01-10T17:22:48.200 回答