【问题标题】:C# What event do I use to do something when a button is created?C# 创建按钮时我使用什么事件来做某事?
【发布时间】:2014-08-13 01:21:28
【问题描述】:

好的,我不知道该怎么做,因为我正在尝试自学 C# 并同时创建一个工作程序。

我有一个 IP 地址列表:

List<IPAddress> addresses

一旦将列表提交到表单,我就会动态地为这些 IP 地址创建一组按钮。

当按钮被创建时,我需要使用什么事件来启动一个函数来做某事?

更多信息: 遍历 IP 地址列表,并为 TableLayoutPanel 中的每个 IP 地址创建按钮。

当在面板内的表单上创建这些按钮时,我想要一个调用的函数,该函数将在以下位置传递 IPAddress:

b.Tag = String.Format("{0}.{1}.{2}.{3}", ba[0], ba[1], ba[2], ba[3]);

并异步 ping 该 IP 地址。

如果 Ping 返回 true,我希望按钮从默认颜色变为绿色。 如果 ping 返回 false,我希望按钮从默认颜色变为红色。

编辑:::::: 我将添加我现在创建 FLP、TBL 和按钮的代码。创建每个按钮后,我想调用一个 ping 函数来 ping 该按钮的 IP 地址,并根据 ping 返回的方式更改其颜色。我不知道如何设置它,也不知道该功能会是什么样子。我试过 b.control.added 但它永远不会被触发。如果我只执行 tbl.control.add 它将触发它没有我需要传递给函数(IPAddress)的信息还是它?就像我说的 C# 的新手,自 2005 年以来没有真正编程过太多,所以远离游戏。

public partial class Form2 : Form
{
    public Form2(List<IPAddress> addresses)
  {
    InitializeComponent();

    FlowLayoutPanel flp = new FlowLayoutPanel();
    flp.AutoScroll = true;
    flp.FlowDirection = FlowDirection.TopDown;
    flp.Location = new System.Drawing.Point(12, 67);
    flp.AutoSize = true;
    flp.Height = 600;
    flp.WrapContents = false;
    foreach (var ipa in addresses)
    {
        TableLayoutPanel tlp = new TableLayoutPanel();
        tlp.AutoSize = true;
        tlp.Dock = DockStyle.Fill;
        tlp.RowCount = 0;
        tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));
        tlp.ColumnCount = 0;
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        Label lbl = new Label();
        lbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        lbl.Location = new System.Drawing.Point(3, 40);
        lbl.Size = new System.Drawing.Size(130, 50);
        lbl.Dock = DockStyle.Fill;
        lbl.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
        Byte[] ba = ipa.GetAddressBytes();
        lbl.Text = String.Format("{0}.{1}.{2}.{3}", ba[0], ba[1], ba[2], ba[3]);
        tlp.Controls.Add(lbl, 0, 0);
        Button b = new Button();
        b.Text = "Router\n\r" + String.Format("{0}.{1}.{2}.126", ba[0], ba[1], ba[2]);
        b.Tag = String.Format("{0}.{1}.{2}.126", ba[0], ba[1], ba[2]);
        b.Dock = DockStyle.Fill;
        b.Click += btnRouter_Click;
        b.Size = new System.Drawing.Size(150, 50);
        b.ControlAdded += btnRouter_ControlAdded;
        tlp.Controls.Add(b, 1, 0);
        b = new Button();
        b.Text = "Switch\n\r" + String.Format("{0}.{1}.{2}.57", ba[0], ba[1], ba[2]);
        b.Tag = String.Format("{0}.{1}.{2}.57", ba[0], ba[1], ba[2]);
        b.Dock = DockStyle.Fill;
        b.Click += btnSwitch_Click;
        b.Size = new System.Drawing.Size(150, 50);
        b.ControlAdded += btnSwitch_ControlAdded;
        tlp.Controls.Add(b, 2, 0);
        b = new Button();
        b.Text = "Steelhead\n\r" + String.Format("{0}.{1}.{2}.7", ba[0], ba[1], ba[2]);
        b.Tag = String.Format("{0}.{1}.{2}.7", ba[0], ba[1], ba[2]); 
        b.Dock = DockStyle.Fill;
        b.Click += btnSteelhead_Click;
        b.Size = new System.Drawing.Size(150, 50);
        b.ControlAdded += btnSteelhead_ControlAdded;
        tlp.Controls.Add(b, 3, 0);
        b = new Button();
        b.Text = "InPath\n\r" + String.Format("{0}.{1}.{2}.8", ba[0], ba[1], ba[2]);
        b.Tag = String.Format("{0}.{1}.{2}.8", ba[0], ba[1], ba[2]);
        b.Dock = DockStyle.Fill;
        b.Click += btnInPath_Click;
        b.Size = new System.Drawing.Size(150, 50);
        b.ControlAdded += btnInPath_ControlAdded;
        tlp.Controls.Add(b, 4, 0);
        b = new Button();
        b.Text = "Server\n\r" + String.Format("{0}.{1}.{2}.6", ba[0], ba[1], ba[2]);
        b.Tag = String.Format("{0}.{1}.{2}.6", ba[0], ba[1], ba[2]);
        b.Dock = DockStyle.Fill;
  //       b.Click += btnServer_Click;
        b.Size = new System.Drawing.Size(150, 50);
        b.ControlAdded += btnServer_ControlAdded;
        tlp.Controls.Add(b, 5, 0);
        b = new Button();
        b.Text = "NCAP";
        b.Tag = String.Format("{0}.{1}.{2}.", ba[0], ba[1], ba[2]);
        b.Dock = DockStyle.Fill;
        b.Click += btnNCAP_Click;
        b.Size = new System.Drawing.Size(150, 50);
        tlp.Controls.Add(b, 6, 0);
        flp.Controls.Add(tlp);
    }
    this.AutoSize = true;
    this.Controls.Add(flp);
  }

【问题讨论】:

  • 为什么需要活动?只需在创建按钮时调用该函数。

标签: c# button ping


【解决方案1】:

您可以使用 TableLayoutControl 的 ControlAdded 事件,ControlEventArgs 有一个控件属性,即添加的控件。这是你想要的一个快速而肮脏的例子。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.NetworkInformation;

namespace WindowsFormsApplication75
{
   public partial class Form1 : Form
   {
        List<IPAddress> addresses = new List<IPAddress>();
        public Form1()
        {
            InitializeComponent();
            //Add IpAddresses to the List
            addresses.Add(new IPAddress(new byte[] { 65, 55, 72, 135 }));
            addresses.Add(new IPAddress(new byte[] { 8, 8, 8, 8 })); 
            addresses.Add(new IPAddress(new byte[] { 74, 125, 157, 99 }));
            addresses.Add(new IPAddress(new byte[] { 98, 137, 149, 56 }));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Not sure how you are passing in your list I elected to do it with a button click
            foreach (var address in addresses)
            {
                byte[] ba = address.GetAddressBytes(); //Get the IPAddress in a Byte Format for the Button Text
                                                       //Keeping it as an IPAddress in the Tag so I don't have to convert later
                Button b = new Button() { Tag = address, Dock = DockStyle.Fill, Text = String.Format("{0}.{1}.{2}.{3}", ba[0], ba[1], ba[2], ba[3]) };
                tableLayoutPanel1.Controls.Add(b);
            }


        }

        private void tableLayoutPanel1_ControlAdded(object sender, ControlEventArgs e)
        {
            if (e.Control is Button) //Check if control is a Button.
            {     
                //The ControlEventArgs Control Property has the Control that was added to the tableLayoutPanel
                Ping pingIt = new Ping(); //Create the Ping Object
                pingIt.PingCompleted += pingIt_PingCompleted;  //Add the eventHandler
                //used the SendAsync Method that allows and object to be passed as a user token
                //passed in the control that was added so that the background color can be changed
                pingIt.SendAsync((IPAddress)e.Control.Tag,2000,e.Control);
            }

        }

        void pingIt_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            Control ctrl = (Control)e.UserState;
            if (ctrl.Text != "NCAP")
            {
                if (e.Reply.Status == IPStatus.Success)
                {
                    ctrl.BackColor = Color.Green;
                }
                else
                {
                    ctrl.BackColor = Color.Red;
                }
            }
        }
    }
}

示例运行:

【讨论】:

  • 您的代码不会影响添加到表格布局面板的每个控件吗?甚至我不希望背景更改的标签和最后一个按钮 (NCAP)。
【解决方案2】:

我不知道你到底想要什么,但我认为我的指导对你有所帮助。

使用以下代码,您可以动态地向表单添加按钮:

        //instantiate and initialize your button
        Button b = new Button();
        b.Name = "btnShaun";
        b.Text = "SomthingYouWant";

        //in here you add this button to your form
        this.Controls.Add(b);

        //and here you set it's position in your form
        this.Controls["btnShaun"].Location = new Point(200, 100);

现在,Form 类有一个名为 ControlAddedEvent。这是Event的VS描述:

"Occures when a control is added to this control"

所以你可以在这个事件中使用你的函数

【讨论】:

  • 我实际上已经尝试过了,但是 b.ControlAdded += btnTest_ControlAdded;永远不会被触发,只有当我将它命名为 tbl.ControlAdded += btnRouter_ControlAdded;然后它没有得到给b.tag的ip地址信息。
【解决方案3】:

表单有一个 ControlAdded 事件,您可以将其用于此目的。但我不清楚你为什么需要这样做。只需在创建按钮时调用 b.Tag = ...。

【讨论】:

    【解决方案4】:

    这是工作代码,检查我是如何添加 ControlAdded 事件处理程序的。 ControlAdded 事件处理程序附加到正在添加控件的父级或容器,而不是控件(按钮)本身。

    您的案例处理程序需要附加到您正在使用的面板上。您也可以为此使用设计器窗口。

    在本例中,我已将其附加到 form1(this)。

    using System;
    using System.Linq;
    using System.Windows.Forms;
    using System.Net;
    using System.Collections.Generic;
    
    namespace WindowsFormsApplication1
    {
      public partial class Form1 : Form
       {
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
            List<IPAddress> addresses;
    
    
            IPHostEntry heserver = Dns.GetHostEntry("192.168.1.254");
            addresses = heserver.AddressList.ToList();
    
            int count = 0;
    
            this.ControlAdded += new  System.Windows.Forms.ControlEventHandler(this.button_added);
    
            foreach (var addr in addresses)
            {
                count += 1;
                Button b = new Button();
                b.Name = "button1";
                b.Text = addr.ToString();
                b.Size = new System.Drawing.Size(100 + ((count-1) * 100), 50);
                b.Click += new System.EventHandler(button1_Click);
                this.Controls.Add(b);
            }           
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Button 1 clicked");
        }
    
        private void button_added(object sender, EventArgs e)
        {
            MessageBox.Show("Button 1 added");
        }
    
    
      }
    }
    

    【讨论】:

      【解决方案5】:

      您可以订阅父控件的ControlAdded event,正如其他答案所建议的那样。这会起作用,但对我来说似乎不优雅。父级不应对其子级的实现细节负责。事实上,好的设计不仅要求它不负责任,而且它甚至不知道这样的事情。

      更好的设计是让子控件自己处理这个逻辑。为此,您需要创建一个继承自标准控件的自定义类。然后,在您的自定义控件类中,您将覆盖OnCreateControl method。从该方法内部,您可以编写代码来执行您想要的任何初始化。 (这与 WinForms 框架用于调用 OnLoad 方法的方法相同,该方法会为 Form 类引发 Load 事件。)

      这种设计的优点是逻辑完全独立。这意味着 (1) 子控件的实现细节不必泄露给父控件,并且 (2) 这种类型的 所有 子控件的行为方式完全相同,无需您的必须复制代码。

      还有OnHandleCreated method 毫无价值。每次控件必须重新创建其底层 Win32 窗口时都会调用它,这会产生一个新的窗口句柄。从技术上讲,这是一个您应该可以完全忽略的实现细节。在您不知道的情况下,可以出于多种原因重新创建句柄,例如,为了响应您更改控件的某些属性。这意味着可以在控件的生命周期内多次调用此方法。但是,如果您的任何逻辑需要访问控件的 Handle 属性,则需要使用此方法而不是 OnCreateControl。否则,为了简单起见,首选OnCreateControl

      实际上,如果您所做的只是设置控件的 Tag 属性,您可以在自定义控件的 构造函数 中执行此操作,而无需覆盖 OnCreateControl 或 @987654335 @ 财产。设置Tag 属性不需要创建控件。

      【讨论】:

      • 标签属性已从每个控件中设置。我试图找到一种方法来根据 ping 如何返回到传递给按钮的 .tag 属性的地址列表中的 IP 地址来更改按钮的背景颜色。我只是无法/无法理解在创建按钮时或之后触发 Ping 命令的方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 2020-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多