gpt4 book ai didi

c# - Winforms 事件架构

转载 作者:行者123 更新时间:2023-12-04 04:02:29 24 4
gpt4 key购买 nike

尝试在 winforms 中构建一个简单的应用程序,但我注意到我对 winforms 模型中的事件的理解存在差距。我知道我已经很接近解决方案了,但是有些事情我不知道如何使用“winforms 方式”

这是我要完成的 UI 布局。 Form1 是通过 VS2019 模板生成的,但是 LeftSide 和 RightSide 是我构建的两个独立的类。

*****Form1************************
| |
| **LeftSide*** **RightSide** |
| | | | | |
| | _TextBox | | _TextBox | |
| | _Button | | _Button | |
| | | | | |
| | | | | |
| ************* ************* |
| |
**********************************

左侧和右侧:

  • 返回一个带有文本框和按钮的面板
  • 具有未公开的“子”控件(即类本身负责 UI 布局和数据验证)
  • 需要互相交流和Form1交流
  • 没有继承任何东西;它们通过命名空间在 Form1 中使用
  • 在 Form1 中实例化

这是(一个不完整的)Form1,不知道要在这里添加什么

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

这是 LeftSide 和 RightSide 类(请注意,它们是相同的,只是将“左”一词替换为“右”)

namespace myapp.LeftSide
{
class LeftSide
{
private Panel LeftSide_Panel = new Panel();
private Textbox LeftSide_TextBox = new Textbox();

private Button LeftSide_Button = new Button();

private string LeftSide_Data; //store TextBox.text here

public ReturnPanel()
{
//return a Panel that Form1 can use
LeftSide_Panel.Controls.Add(LeftSide_Button);
LeftSide_Panel.Controls.Add(LeftSide_TextBox);
return this.LeftSide_Panel;
}
}
}

我知道我可以通过在 LeftSide 中创建一个函数来为 LeftSide_Button 创建一个自定义事件处理程序,如下所示:

private void LeftSide_Button_Click(object sender, EventArgs e)
{
//read the textbox, assume it is valid and store the string in our LeftSide_Data
this.LeftSide_Data = this.LeftSide_TextBox.Text;
}

如果我想将数据保留在类的本地,则上述方法可行,但我不知道如何将 LeftSide_Button_Click 主要暴露给 Form1,有时暴露给 RightSide。

我的问题是:

  • 如果 LeftSide 拥有其文本框内的数据(并存储在 LeftSide_Data 中)并且 LeftSide_Button_Click 是我的自定义验证事件(为简化起见,上面未显示验证)Form1 如何不仅成为通知按钮已被点击但也发送了 LeftSide_Data 中的字符串?
  • 如何向任何想要订阅的人公开 LeftSide 事件?是使用“delegate”关键字还是“event”关键字?或者是其他东西?基于事件的关键字太多,因此是混淆的主要来源。
  • 是否应该将 private void LeftSide_Button_Click(object sender, EventArgs e) 从返回 void 更改为 private Eventhandler LeftSide_Button_Click(object sender, EventArgs e) 如果是这样,是什么我回来了……EventHandler 是由什么“制成”的?

编辑:我找到了下图,即使它没有随事件一起传递数据,实现它是否是朝着正确方向迈出的一步? enter image description here

最佳答案

您可以声明一个代表您的自定义事件的签名 的委托(delegate),提供您希望传递的任意数量的参数。然后您只需声明该委托(delegate)类型的事件。任何人都可以订阅您的自定义事件,以便在事件发生时收到通知。

这是一个简单的示例,其中委托(delegate)名为 dlgLeftSideData,事件名为 LeftSideData。它传递发送者(LeftSide 产生事件的实例)以及字符串数据。还有一个公共(public)只读属性,您可以根据需要通过发件人访问该属性。我已经连接了按钮的点击事件以进行“验证”,然后如果有任何订阅者它会引发自定义事件:

class LeftSide
{

public event dlgLeftSideData LeftSideData;
public delegate void dlgLeftSideData(LeftSide sender, string data);

private Panel LeftSide_Panel = new Panel();
private TextBox LeftSide_TextBox = new TextBox();
private Button LeftSide_Button = new Button();

public LeftSide()
{
LeftSide_TextBox.Location = new Point(5, 5);
LeftSide_Button.Location = new Point(5, 25);
LeftSide_Panel.Controls.Add(LeftSide_TextBox);
LeftSide_Panel.Controls.Add(LeftSide_Button);

LeftSide_Button.Click += LeftSide_Button_Click;
}

private void LeftSide_Button_Click(object sender, EventArgs e)
{
if (true) // some kind of validation
{
LeftSideData?.Invoke(this, this.Data); // raise the event if there are any subscribers
}
}

public string Data
{
get
{
return LeftSide_TextBox.Text;
}
}

public Panel LeftSidePanel
{
get {
return this.LeftSide_Panel;
}
}

}

下面是 Form1 中的示例代码,它订阅自定义事件并对接收到的数据执行某些操作:

public partial class Form1 : Form
{

LeftSide ls = new LeftSide();

public Form1()
{
InitializeComponent();
this.Controls.Add(ls.LeftSidePanel);
ls.LeftSideData += Ls_LeftSideData;
}

private void Ls_LeftSideData(LeftSide sender, string data)
{
label1.Text = data;
// or we could use "sender" somehow as well
label1.Text = sender.Data; // get value from the read-only property
}

}

您可以在您的类中创建一个属性或方法来接收对另一个 LeftSide/RightSide 的引用并在内部订阅事件。

关于c# - Winforms 事件架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62866364/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com