C# windows窗体应用程序中的用户控件

C# windows窗体应用程序中的用户控件,c#,winforms,C#,Winforms,我有一个简单的用户控件,其中有一个文本框和标签。当我在另一个窗体中使用用户控件时,我创建了公共属性来访问文本框中的文本 我的问题是,当我在表单中调用该属性时,该属性返回空值。我遗漏了什么吗 我的财产如下: public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); } p

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

我的问题是,当我在表单中调用该属性时,该属性返回空值。我遗漏了什么吗

我的财产如下:

 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)

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

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

您的UserControl名称和图标应该显示在工具箱的顶部,您只需将其拖动到主窗体即可。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";
}
如果用户控件的默认文本框字段为空,那么上面两行代码返回null或String.empty check via String.IsNullOrEmpty似乎是正确的,因为您显式创建了用户控件的新实例

我想你真正想要的是:

您已将用户控件插入设计器中的窗体中。让我们调用这个用户控件实例ctlUser

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

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


当您说属性返回空值时,您的确切意思是什么?它实际上是空的,还是您的MessageBox简单地显示为空

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

另外,你处理这件事的方式有点不寻常

首先,线路:

UserControl1 Usc = new UserControl1(); 
通常不需要像这样实例化用户控件。相反,您可以将控件从工具箱拖到窗体的设计图面上。这将负责为您实例化和初始化控件

我认为这实际上是您的问题-当您包括上面的代码行时,您正在创建用户控件的新实例,而这与您拖到设计器上的用户控件没有任何关系

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

第二,接下来的两行:

string Make = Usc.rtnTxtMake;  

MessageBox.Show(Make)  
您可以直接访问属性rtnTxtMake。除非以后需要在代码的其余部分访问Make字符串,否则直接访问属性通常被认为是更好的样式

MessageBox.Show(userControl.rtnTxtMake);

你是否将txtMake.Text设置为任何值?当我运行应用程序时,我在文本框中输入值。这还不够吗?当我将txtMake.Text指定给某个值时,手动进行。我能够获得所需的输出。但是如何将运行时键入的值指定给txtMake.Text,匈牙利符号在运行时为响应按钮单击而创建UserControl没有什么错!其他注释/答案已经提醒您:您需要将其添加到有效的容器表单、面板等中才能使用它,并且您必须在按钮单击事件中这样做:因为您创建的UserControl在单击事件退出时将超出范围。在大多数情况下,您希望保留对新创建的UserControl的引用,以便以后访问它:这是在表单范围级别声明的特定变量,还是列表中的条目,取决于您的设计和意图。谢谢..我指的是新实例..抱歉@David,次要观察:由于变量是在私有按钮单击处理程序的作用域中描述的,因此在该作用域之外是无法访问的:当然,您是正确的,像这样一次性声明变量是浪费时间的。@Ash我经常在运行时创建UserControls;imho:并非罕见或不正常的做法。当然,您正确地指出,任何运行时创建的控件在添加到某个containe之前都可能是无用的 R但是,也有例外:我使用运行时创建的。party TreeView实例:从不添加到任何容器中:它允许将UI TreeView中的选定节点保存为XML表示TreeView仅允许将整个TreeView保存为XML。我将UI树视图中的选定节点克隆到ghost树视图中,将ghost树视图保存为XML,然后清除ghost。
MessageBox.Show(userControl.rtnTxtMake);