【问题标题】:User control in windows forms applicationWindows 窗体应用程序中的用户控件
【发布时间】:2010-01-10 08:20:16
【问题描述】:

我有一个简单的用户控件,里面有一个文本框和标签。当我在其他表单中使用用户控件时,我创建了公共属性来访问文本框中的文本。

我的问题是当我在表单中调用它时该属性返回空值。我错过了什么吗?

我的财产如下::

 public partial class UserControl1 : UserControl
 {
        public UserControl1()
        {
            InitializeComponent();
        }

        public string rtnTxtMake
        {  
            get 
            { 
                return txtMake.Text; 
            }
            set 
            { 
                txtMake.Text = value; 
            } 
        }
 }

在下一个表单按钮单击事件中,我按如下方式调用该属性

        UserControl1 Usc = new UserControl1();
        string Make = Usc.rtnTxtMake;

        MessageBox.Show(Make)

【问题讨论】:

  • 您是否曾将txtMake.Text 设置为任何值?
  • 我在运行应用程序时在文本框中输入值。这还不够吗?
  • 手动当我将 txtMake.Text 分配给某个值时。我能够获得所需的输出。但是如何将运行时键入的值分配给 txtMake.Text??????? ?
  • Ewww,匈牙利符号
  • 在运行时创建 UserControl 以响应 Button Click 并没有错!其他 cmets/answers 已经提醒您:您需要将其添加到有效的“容器”(表单、面板等)中才能使用它,并且您将在 Button Click 事件中执行此操作:因为您创建的 UserControl Click 事件退出时将“超出范围”。在大多数情况下,您需要保留对新创建的 UserControl 的引用以便以后访问它:无论是在表单范围级别声明的特定变量,还是 List 中的条目,都取决于您的设计和意图。

标签: c# winforms


【解决方案1】:
UserControl1 Usc = new UserControl1();
string Make = Usc.rtnTxtMake;

如果您的用户控件默认有一个空的文本框字段,那么上面两行代码将返回nullString.Empty(通过String.IsNullOrEmpty 检查)似乎是正确的,因为您明确地创建了一个新的您的用户控件的实例。

我想你真正想要的是这个:

  • 您已将用户控件插入到 Designer 的表单中。我们称这个用户控件实例为ctlUser

  • 您有一个带有Click 事件处理程序的按钮。您问题中的最后几行代码来自该处理程序方法。

  • 在处理程序中,您不会创建用户控件的新实例 (Usc),而是引用您之前插入到表单中的实例,ctlUser。那么事情应该会按预期进行。

【讨论】:

  • 谢谢..我指的是新实例..对不起!!
【解决方案2】:

您的 UserControl 必须先添加到父窗体/控件的 Controls 集合中,然后才能正确初始化。通常您不会自己编写创建和添加 UserControl 的代码。

相反,首先构建您的项目,然后转到主窗体的 Deisgner 视图并查看工具箱。

您的用户控件名称(和一个图标)应该出现在工具箱的顶部,您可以简单地将其拖到主窗体中。 Windows 窗体设计器会自动为您生成所需的初始化代码。

您不应在按钮单击事件处理程序中创建控件的新实例。使用设计器方法创建控件,您可以简单地访问控件的现有实例,如下所示:

public void button_Click(object sender, EventArgs e)
{
    // myUserControl1 has already been created and initialized by the Deisgner generated code
    // Note the name 'myUserControl1' is just an example, yours may be different.
    string controlText=myUserControl1.rtnTxtMake;

    // Or to change the UserControl textbox value
    myUserControl1.rtnTxtMake="Testing";
}

【讨论】:

  • @Ash 我经常在运行时创建用户控件;恕我直言:并不少见或“异常”的做法。当然,您正确地指出,任何运行时创建的控件在添加到某个“容器”之前可能都是“无用的”。但是,也有例外:我使用运行时创建的 3rd。派对 TreeView 实例:从未添加到任何容器:它允许将 UI TreeView 中的选定节点保存为 XML(说 TreeView 仅允许将整个 TreeView 保存为 XML)。我将 UI 的 TreeView 中选定的节点克隆到“ghost”TreeView 中,将“ghost”TreeView 保存为 XML,然后清除“ghost”。
【解决方案3】:

当您说该属性返回一个空值时,您究竟是什么意思?它实际上是空的,还是你的 MessageBox 简单地显示为空?

我很快复制了您的代码,它的行为完全符合预期 - MessageBox 显示,但它是空的,因为 TextBox 控件的 Text 属性的默认值是一个空字符串。

另外,你处理这个问题的方式有点不寻常。

首先是一行:

UserControl1 Usc = new UserControl1(); 

您通常不需要像这样实例化用户控件。相反,您可以将控件从工具箱拖到表单的设计图面上。这将负责为您实例化和初始化您的控件。

我认为这实际上是您的问题 - 当您包含上面的代码行时,您正在创建用户控件的新实例,这与您拖到设计器上的用户控件无关.

如果您转到表单的设计器视图并单击用户控件,您应该会在此处看到一个属性窗口。如果您不这样做,则从“查看”菜单中选择它,或按 F4。在属性列表中,应该有一个“名称”,这是为您的用户控件生成的程序名称。如果需要,您可以在此处更改它,但是当您在表单的其余部分中引用此控件时,这是您必须使用的。

其次,接下来的两行:

string Make = Usc.rtnTxtMake;  

MessageBox.Show(Make)  

您可以直接访问属性 rtnTxtMake。除非您以后需要在其余代码中访问 Make 字符串,否则直接访问该属性通常会被认为是更好的样式。

MessageBox.Show(userControl.rtnTxtMake);

【讨论】:

  • @David,小观察:由于该变量是在(肯定是私有的)按钮单击处理程序的范围内声明的,因此无论如何都不能在该范围之外访问它:当然你是正确的像这样一次性声明变量是浪费时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-21
相关资源
最近更新 更多