将数据从UserControls传递到WinForm

收割者

新成员
已加入
2021年1月20日
留言内容
3
编程经验
Beginner
我想显示从用户控件生成的数据,以显示在Winfrom(Form1)的文本框中。
数据正在从用户控件解析到Form1,但是我无法获取文本框(tb_config)来接收解析的数据。


(不好意思的英语)



Ok2zffW.png


我使用控制台检查是否从用户控件中解析了文本。 (Winform)

vw9mXFw.png



用户控件内部的代码。

8h4QXnT.png
 
Solution
As for the issue, the problem is that you are creating a new instance of Form1 and operating on that. That will have no effect on the instance that is already displayed and contains the user control and the new instance is discarded immediately. If you want to do anything useful, you need to operate on the existing form not a new one.

You could get access to that form by calling the user control's FindForm method. That would return a Form reference and you could cast it as the appropriate type and then do whatever you want with it.

不过,这是一种狡猾的方式。用户控件除了是窗体外,不应该知道其父窗体的任何特定信息。做事的正确方法...

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,524
地点
悉尼,澳大利亚
编程经验
10+
首先,请不要张贴代码图片。从VS复制代码,并将其作为文本粘贴为帖子,格式为代码。如果我们想执行您的代码,是否真的必须自己编写出来,因为我们无法从您的帖子中复制它?

Secondly, there's no need to declare your own delegates these days. Just use the appropriate Action or Func. For a void method with one string parameter, you would use an Action<string>. You're already doing that in the first snippet so why not do it in the second snippet?

第三,为什么要在第二个片段中创建一个委托?您没有将其传递给任何地方,所以为什么不能直接调用该方法呢?
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,524
地点
悉尼,澳大利亚
编程经验
10+
As for the issue, the problem is that you are creating a new instance of Form1 and operating on that. That will have no effect on the instance that is already displayed and contains the user control and the new instance is discarded immediately. If you want to do anything useful, you need to operate on the existing form not a new one.

You could get access to that form by calling the user control's FindForm method. That would return a Form reference and you could cast it as the appropriate type and then do whatever you want with it.

That is a dodgy way to do it though. The user control shouldn't know anything specific about its parent form other than it's a form. The proper way to do what you want to achieve is for the user control to raise an event and for the form to handle it. The data can be passed via a custom EventArgs object or the form can retrieve the data from a property of the user control. It can then call it own method. If this happens in response to the click of a Button then there's no need to worry about which thread it happens on.
 
解决方案

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,524
地点
悉尼,澳大利亚
编程经验
10+
Using the standard EventArgs:
User Control:
using System;
using System.Windows.Forms;

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

        public string TextBox1Text => textBox1.Text;

        public event EventHandler Button1Clicked;

        private void button1_Click(object sender, EventArgs e)
        {
            OnButton1Clicked(EventArgs.Empty);
        }

        protected virtual void OnButton1Clicked(EventArgs e)
        {
            Button1Clicked?.Invoke(this, e);
        }
    }
}
Form:
using System;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void userControl11_Button1Clicked(object sender, EventArgs e)
        {
            MessageBox.Show(userControl11.TextBox1Text);
        }
    }
}
数据通过属性公开,并且在引发事件时,表单从该属性中提取数据。

Using a custom EventArgs:
EventArgs:
using System;

namespace WindowsFormsApp1
{
    public class CustomEventArgs : EventArgs
    {
        public string Text { get; }

        public CustomEventArgs(string text)
        {
            Text = text;
        }
    }
}
User Control:
using System;
using System.Windows.Forms;

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

        public event EventHandler<CustomEventArgs> Button1Clicked;

        private void button1_Click(object sender, EventArgs e)
        {
            OnButton1Clicked(new CustomEventArgs(textBox1.Text));
        }

        protected virtual void OnButton1Clicked(CustomEventArgs e)
        {
            Button1Clicked?.Invoke(this, e);
        }
    }
}
Form:
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void userControl11_Button1Clicked(object sender, CustomEventArgs e)
        {
            MessageBox.Show(e.Text);
        }
    }
}
数据通过事件公开,并且用户控件在引发事件时将其推送。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,524
地点
悉尼,澳大利亚
编程经验
10+
我尝试了您的方法,但它甚至不显示消息框。
那你做错了。我测试了我的两个示例,并且它们都起作用,因此,如果您的代码不起作用,那么您就不会实现我所举例说明的内容。如果您不告诉我们您做了什么,我们就不会告诉您您做错了什么。

另外,您实际上是否调试过代码,即设置断点,逐行浏览代码并检查每一步的状态?如果不是,那么您还没有真正尝试诊断问题。您知道代码在每一行应该执行的操作,因此您需要在代码执行时对其进行观察,并确切了解其实际行为在何处以及如何与您的期望有所不同。即使您仍然无法解决问题,至少您可以告诉我们更多"it does work"。您可以具体告诉我们您的期望,实际发生的事情以及发生的事情。如果您不知道如何调试,请停止正在做的事情,了解如何操作,然后返回并调试此代码。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,524
地点
悉尼,澳大利亚
编程经验
10+
顺便说一句,您是否真的尝试过创建一个新项目并使用我的确切代码?你应该有。如果您这样做了,那么您可以调试该代码并准确地查看其执行过程以获取全面的了解,然后将相同的原理应用于您自己的项目。许多人想采取捷径并在他们的项目中实现他们不了解的事情,因此他们无法理解为什么他们不起作用。
 
最佳 底部