【问题标题】:Return value from usercontrol after user action用户操作后从用户控件返回值
【发布时间】:2013-06-27 18:19:44
【问题描述】:

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

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

例如:

var item = myUserControl.SelectItem();

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

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

简单地说,我希望用户控件的方法在用户单击其上的特定按钮后返回。

【问题讨论】:

  • 嗯,你的设计怎么样?例如。像@pm_2 这样的表单弹出窗口会出现什么问题?显示用户控件时应该禁用什么?
  • 我假设您想要阻止 UI 样式。顺便说一下,它看起来很棒。在网上你可以找到 jscript 的例子。但我们曾经为我们的前端窗口做过
  • 类似手机的设计。该应用程序有多个页面(构建为 UserControls)。其中一个页面用作选择某些值的小部件。用户单击按钮以确认选择。在 UserControl 中选择值后,父窗体中的代码应对其进行处理。所以本质上,表单加载一个临时的 UserControl 只是为了允许用户选择一个值。
  • 我建议的和模态对话框一样。例如,我们在每次程序遇到低音量时让用户调整麦克风电平。认为这个解决方案是你所需要的。但你当然知道得更好
  • @LoveDotNet 为什么不使用 MDI 表单?并将您的页面(UserControl)视为普通的子窗体。

标签: c# .net winforms user-controls


【解决方案1】:

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

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

因此,就像您从 TextBoxTextBox.TextSelectedValueSelectedItemListBox 中获取值一样,您可以从 UserControl 调用一个方法来返回 SelectedItem。

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

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

编辑:

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

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

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

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

【讨论】:

  • 看起来 OP 希望用户只能与他的 UserControl 进行交互,出于某种原因,修改 UserControl 之外的任何信息/数据可能会导致他的应用程序无法正常工作。所以他希望一切顺利。在某些情况下,您的方法是可以的,但 OP 的情况并非如此。
  • @KingKing,我想我现在看到了 OP 试图实现的目标,并添加了一个我认为他可以遵循以实现他想要的模式的代码示例。
【解决方案2】:

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

【讨论】:

  • 我需要主窗体内的控件。我的想法是让应用程序只有一个表单,但可以按需加载多个不同的页面。
  • 那么您别无选择,只能从用户控件启用/显示事件的其他控件。
【解决方案3】:

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

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

答案很简单: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按钮,用户调用OK函数查询被选择的项目并使选择任务进入完成状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-17
    • 2015-04-30
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多