[英]C# What event do I use to do something when a button is created?
好的,我不確定如何執行此操作,因為我試圖自學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.add但它從未被觸發。 如果僅執行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);
}
您可以使用TableLayoutControl的ControlAdded事件,ControlEventArgs具有一個Control屬性,它是添加的Control。 這是您想要的一個快速而骯臟的例子。
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;
}
}
}
}
}
運行示例:
我不確定您到底想要什么,但我認為我的指導會為您提供幫助。
通過以下代碼,您可以將按鈕動態添加到表單中:
//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
具有一個名為ControlAdded
的Event
。 這是此Event
VS描述:
"Occures when a control is added to this control"
這樣您就可以在此事件中使用您的功能
窗體具有一個ControlAdded事件,可以將其用於此目的。 但是我不清楚為什么您需要這樣做。 創建按鈕時只需調用b.Tag =...。
這是工作代碼,檢查如何添加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");
}
}
}
您可以訂閱父控件的ControlAdded
事件 ,如其他答案所示。 這會起作用,但是對我來說似乎很微不足道。 父母不應對子女的實施細節負責。 實際上,好的設計要求它不僅不負責任,而且甚至不知道這些事情。
更好的設計是讓子控件自行處理此邏輯。 為此,您需要創建一個從標准控件繼承的自定義類。 然后,在您的自定義控件類中,您將覆蓋OnCreateControl
方法 。 從該方法的內部,您可以編寫代碼以執行所需的任何初始化。 (這是WinForms框架用於調用Form
類的OnLoad
方法的同一方法,該方法引發Load
事件。)
這種設計的優點是邏輯完全獨立。 這意味着(1)子控件的實現細節不必泄漏給父控件,並且(2) 所有這種類型的子控件都將以完全相同的方式運行,而不必重復代碼。
這是值得什么, 還有一個OnHandleCreated
方法 。 每次控件必須重新創建其基礎Win32窗口時,都會調用此方法,這將導致一個新的窗口句柄。 從技術上講,這是實現細節,您應該可以完全忽略。 可能由於多種原因而無需您的明確知識就可以重新創建該句柄,例如,響應於更改控件的某些屬性。 這意味着在控件的生命周期中可以多次調用此方法。 但是,如果任何邏輯都需要訪問控件的Handle
屬性,則需要使用此方法代替OnCreateControl
。 否則,為簡單起見,最好使用OnCreateControl
。
實際上,如果您要做的只是設置控件的Tag
屬性,則可以在自定義控件的構造函數中執行此操作,而無需覆蓋OnCreateControl
或OnHandleCreated
屬性。 設置Tag
屬性不需要創建控件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.