好的,我不知道如何做到这一点,因为我正在尝试自学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,我希望按钮从其默认颜色变为红色。
EDIT ::::: 我将添加我现在正在创建FLP,TBL和按钮的代码。创建每个按钮时,我想调用ping函数来ping该按钮的IP地址,并根据ping返回的方式更改颜色。我不知道如何设置它或者功能将是什么样的。我试过b.control.added但它永远不会被触发。如果我执行tbl.control.added,它将触发它,但它没有我需要传递给函数(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);
}
答案 0 :(得分:1)
您可以使用TableLayoutControl的ControlAdded事件,ControlEventArgs有一个Control Property,它是添加的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;
}
}
}
}
}
运行示例:
答案 1 :(得分:0)
我不知道你想要什么,但我认为我的指导可以帮助你。
使用以下代码,您可以动态地向表单添加一个按钮:
//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
有Event
名为ControlAdded
。这是这个Event
的VS描述:
"Occures when a control is added to this control"
所以你可以在这个事件中使用你的功能
答案 2 :(得分:0)
Form有一个ControlAdded事件,您可以将其用于此目的。但我不清楚为什么你需要这样做。只需在创建按钮时调用b.Tag = ...
答案 3 :(得分:0)
这是工作代码,检查我是如何添加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");
}
}
}
答案 4 :(得分:0)
您可以订阅父控件ControlAdded
event,正如其他答案所示。这样可行,但对我来说似乎不太优雅。家长不应对其子女的实施细节负责。事实上,良好的设计要求它不仅不负责任,而且它甚至不知道这样的事情。
更好的设计是让子控件自己处理这个逻辑。要实现此目的,您需要创建一个继承自标准控件的自定义类。然后,在您的自定义控件类中,您将覆盖OnCreateControl
method。从该方法的内部,您可以编写代码来执行您想要的任何初始化。 (这与WinForms框架用于调用OnLoad
方法的方法相同,后者为Load
类引发了Form
事件。)
这种设计的优点是逻辑完全独立。这意味着(1)子控件的实现细节不必泄漏给父控件,并且(2)这种类型的所有子控件的行为方式完全相同,无需复制代码。
还 OnHandleCreated
method是没有价值的。每次控件必须重新创建其基础Win32窗口时调用此方法,这将导致新的窗口句柄。从技术上讲,这是一个您应该能够完全忽略的实现细节。在没有您明确知识的情况下,可以出于多种原因重新创建句柄,例如,响应您更改控件的某些属性。这意味着在控制生命周期内可以多次调用此方法。但是,如果您的任何逻辑需要访问控件的OnCreateControl
属性,则需要使用此方法而不是Handle
。否则,为简单起见,请更喜欢OnCreateControl
。
实际上,如果您正在设置控件的Tag
属性,则可以在自定义控件的构造函数中执行此操作,无需覆盖OnCreateControl
或OnHandleCreated
属性。设置Tag
属性不需要创建控件。