c# 如何创建按钮并稍后通过 ID 删除它们
c# How to create buttons and delete them later by an ID
我正在努力创建这个生成好友请求的脚本。我需要专门为每个按钮和标签添加一个 id,以便在用户单击接受或拒绝按钮时将其删除。
Button reqAccept;
Button reqReject;
Label reqUserName;
private void loadFriendRequests()
{
using (SqlConnection connection = new SqlConnection(con))
{
using (SqlCommand cmd = new SqlCommand("Select UserFirstName, UserLastName, FriendEmail From PendingRequests Where FriendEmail = @fe", connection))
{
connection.Open();
cmd.Parameters.AddWithValue("@fe", Properties.Settings.Default.Email);
using (SqlDataReader dr = cmd.ExecuteReader())
{
i = 0;
while (dr.Read())
{
i++;
foreach (object request in i.ToString())
{
Label userName = new Label();
Button accept = new Button();
Button reject = new Button();
accept.Click += Accept_Click;
reject.Click += Reject_Click;
userName.Text = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(dr["UserFirstName"].ToString() + " " + dr["UserLastName"].ToString());
accept.Text = "Accept";
reject.Text = "Reject";
friendRequestPanel.Controls.Add(userName);
friendRequestPanel.Controls.Add(accept);
friendRequestPanel.Controls.Add(reject);
reqAccept = accept;
reqReject = reject;
reqUserName = userName;
}
}
}
}
}
Requests.Start();
}
private void Reject_Click(object sender, EventArgs e)
{
friendRequestPanel.Controls.Remove(reqUserName);
friendRequestPanel.Controls.Remove(reqAccept);
friendRequestPanel.Controls.Remove(reqReject);
updateFriendRequestDatabase(2);
}
private void Accept_Click(object sender, EventArgs e)
{
friendRequestPanel.Controls.Remove(reqUserName);
friendRequestPanel.Controls.Remove(reqAccept);
friendRequestPanel.Controls.Remove(reqReject);
updateFriendRequestDatabase(1);
}
代码的作用:
上面的代码正在选择与用户电子邮件相同的请求,对于每个好友请求,它将通过使用标签和 2 个接受或拒绝按钮将其添加到 'FlowLayourPanel'。
这是 GUI 的样子:GUI
当用户点击一个按钮时,它显然会转到事件处理程序,但我如何识别按下了哪个按钮?
它需要像这样:
friendRequestPanel.Controls.Remove(reqUserName##ID##);
要做的第一件事是从您的查询中检索唯一标识您的数据的值。假设您的 PendingRequest table 有一个 IDRequest 那么您的查询可以更改为
using (SqlCommand cmd = new SqlCommand(@"Select IDRequest, UserFirstName,
UserLastName, FriendEmail
From PendingRequests
Where FriendEmail = @fe", connection))
现在,当您动态创建控件时,您还将该 ID 添加到由该记录创建的每个控件的标签 属性
foreach (object request in i.ToString())
{
Label userName = new Label();
Button accept = new Button();
Button reject = new Button();
int idRequest = Convert.ToInt32(dr["IDRequest"]);
userName.Tag = idRequest;
accept.Tag = idRequest;
reject.Tag = idRequest;
....
最后,在您的点击事件中,您可以使用如下代码检索按钮和标签的确切实例
private void Reject_Click(object sender, EventArgs e)
{
Button c = sender as Button;
int idRequest = Convert.ToInt32(c.Tag);
var ctrls = friendRequestPanel.Controls
.Cast<Control>()
.Where(x => x.Tag != null &&
Convert.ToInt32(x.Tag) == idRequest)
.ToList();
foreach(Control ct in ctrls)
{
friendRequestPanel.Controls.Remove(ct);
ct.Dispose();
}
updateFriendRequestDatabase(2);
}
请注意,如果您从 Controls 集合中删除控件,则不应忘记对其进行处置。
@Steve 回答得很好。他已经向您展示了如何修复当前代码。
我想向您建议一种更好的方式来构建您当前的代码,这样它看起来更清晰并且您可以更好地控制好友请求功能。如果您有兴趣,请进一步阅读。如果您的截止日期很紧,请忽略 :)。
如果我处在你的位置,我会创建一个用户控件来表示个人好友请求,并在 accept/reject 的情况下使用事件通知主窗体,以便它可以从 panel/list.这样主窗体代码(设计器+代码隐藏)将变得更易于阅读和理解。
FriendRequestControl
这将是标准 UserControl
,其中包含 1 个 Label
(用于显示朋友的姓名和 2 个 Buttons
接受和拒绝。
public partial class FriendRequestControl : UserControl
{
public event EventHandler Accepted;
public event EventHandler Rejected;
public FriendRequestControl()
{
InitializeComponent();
}
public int RequestId { get; set; }
public string FriendName { set { lblFriend.Text = value; } } // TODO add empty/null checks on value
private void Accept_Click(object sender, EventArgs e)
{
UpdateRequest(1);
OnAccepted();
}
private void Reject_Click(object sender, EventArgs e)
{
UpdateRequest(2);
OnRejected();
}
private bool UpdateRequest(int flag)
{
// Update db using RequestId and flag
// TODO Return True/False based if update succeeds
return true;
}
private void OnAccepted()
{
var acceptedHandler = Accepted;
if (acceptedHandler != null)
{
acceptedHandler(this, EventArgs.Empty);
}
}
private void OnRejected()
{
var rejectedHandler = Rejected;
if (rejectedHandler != null)
{
rejectedHandler(this, EventArgs.Empty);
}
}
}
主窗体
private void Form1_Load(object sender, EventArgs e)
{
// Showing just 1 request here
var friendRequest = new FriendRequestControl
{
RequestId = 100, // As Steve mentioned, you db must return this.
FriendName = "Friend 1"
};
friendRequest.Accepted += FriendRequest_Accepted;
friendRequest.Rejected += FriendRequest_Rejected;
flowLayoutPanel1.Controls.Add(friendRequest);
}
private void FriendRequest_Rejected(object sender, EventArgs e)
{
var friendRequest = sender as FriendRequestControl;
flowLayoutPanel1.Controls.Remove(friendRequest);
}
private void FriendRequest_Accepted(object sender, EventArgs e)
{
var friendRequest = sender as FriendRequestControl;
flowLayoutPanel1.Controls.Remove(friendRequest);
}
我正在努力创建这个生成好友请求的脚本。我需要专门为每个按钮和标签添加一个 id,以便在用户单击接受或拒绝按钮时将其删除。
Button reqAccept;
Button reqReject;
Label reqUserName;
private void loadFriendRequests()
{
using (SqlConnection connection = new SqlConnection(con))
{
using (SqlCommand cmd = new SqlCommand("Select UserFirstName, UserLastName, FriendEmail From PendingRequests Where FriendEmail = @fe", connection))
{
connection.Open();
cmd.Parameters.AddWithValue("@fe", Properties.Settings.Default.Email);
using (SqlDataReader dr = cmd.ExecuteReader())
{
i = 0;
while (dr.Read())
{
i++;
foreach (object request in i.ToString())
{
Label userName = new Label();
Button accept = new Button();
Button reject = new Button();
accept.Click += Accept_Click;
reject.Click += Reject_Click;
userName.Text = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(dr["UserFirstName"].ToString() + " " + dr["UserLastName"].ToString());
accept.Text = "Accept";
reject.Text = "Reject";
friendRequestPanel.Controls.Add(userName);
friendRequestPanel.Controls.Add(accept);
friendRequestPanel.Controls.Add(reject);
reqAccept = accept;
reqReject = reject;
reqUserName = userName;
}
}
}
}
}
Requests.Start();
}
private void Reject_Click(object sender, EventArgs e)
{
friendRequestPanel.Controls.Remove(reqUserName);
friendRequestPanel.Controls.Remove(reqAccept);
friendRequestPanel.Controls.Remove(reqReject);
updateFriendRequestDatabase(2);
}
private void Accept_Click(object sender, EventArgs e)
{
friendRequestPanel.Controls.Remove(reqUserName);
friendRequestPanel.Controls.Remove(reqAccept);
friendRequestPanel.Controls.Remove(reqReject);
updateFriendRequestDatabase(1);
}
代码的作用: 上面的代码正在选择与用户电子邮件相同的请求,对于每个好友请求,它将通过使用标签和 2 个接受或拒绝按钮将其添加到 'FlowLayourPanel'。
这是 GUI 的样子:GUI
当用户点击一个按钮时,它显然会转到事件处理程序,但我如何识别按下了哪个按钮?
它需要像这样:
friendRequestPanel.Controls.Remove(reqUserName##ID##);
要做的第一件事是从您的查询中检索唯一标识您的数据的值。假设您的 PendingRequest table 有一个 IDRequest 那么您的查询可以更改为
using (SqlCommand cmd = new SqlCommand(@"Select IDRequest, UserFirstName,
UserLastName, FriendEmail
From PendingRequests
Where FriendEmail = @fe", connection))
现在,当您动态创建控件时,您还将该 ID 添加到由该记录创建的每个控件的标签 属性
foreach (object request in i.ToString())
{
Label userName = new Label();
Button accept = new Button();
Button reject = new Button();
int idRequest = Convert.ToInt32(dr["IDRequest"]);
userName.Tag = idRequest;
accept.Tag = idRequest;
reject.Tag = idRequest;
....
最后,在您的点击事件中,您可以使用如下代码检索按钮和标签的确切实例
private void Reject_Click(object sender, EventArgs e)
{
Button c = sender as Button;
int idRequest = Convert.ToInt32(c.Tag);
var ctrls = friendRequestPanel.Controls
.Cast<Control>()
.Where(x => x.Tag != null &&
Convert.ToInt32(x.Tag) == idRequest)
.ToList();
foreach(Control ct in ctrls)
{
friendRequestPanel.Controls.Remove(ct);
ct.Dispose();
}
updateFriendRequestDatabase(2);
}
请注意,如果您从 Controls 集合中删除控件,则不应忘记对其进行处置。
@Steve 回答得很好。他已经向您展示了如何修复当前代码。
我想向您建议一种更好的方式来构建您当前的代码,这样它看起来更清晰并且您可以更好地控制好友请求功能。如果您有兴趣,请进一步阅读。如果您的截止日期很紧,请忽略 :)。
如果我处在你的位置,我会创建一个用户控件来表示个人好友请求,并在 accept/reject 的情况下使用事件通知主窗体,以便它可以从 panel/list.这样主窗体代码(设计器+代码隐藏)将变得更易于阅读和理解。
FriendRequestControl
这将是标准 UserControl
,其中包含 1 个 Label
(用于显示朋友的姓名和 2 个 Buttons
接受和拒绝。
public partial class FriendRequestControl : UserControl
{
public event EventHandler Accepted;
public event EventHandler Rejected;
public FriendRequestControl()
{
InitializeComponent();
}
public int RequestId { get; set; }
public string FriendName { set { lblFriend.Text = value; } } // TODO add empty/null checks on value
private void Accept_Click(object sender, EventArgs e)
{
UpdateRequest(1);
OnAccepted();
}
private void Reject_Click(object sender, EventArgs e)
{
UpdateRequest(2);
OnRejected();
}
private bool UpdateRequest(int flag)
{
// Update db using RequestId and flag
// TODO Return True/False based if update succeeds
return true;
}
private void OnAccepted()
{
var acceptedHandler = Accepted;
if (acceptedHandler != null)
{
acceptedHandler(this, EventArgs.Empty);
}
}
private void OnRejected()
{
var rejectedHandler = Rejected;
if (rejectedHandler != null)
{
rejectedHandler(this, EventArgs.Empty);
}
}
}
主窗体
private void Form1_Load(object sender, EventArgs e)
{
// Showing just 1 request here
var friendRequest = new FriendRequestControl
{
RequestId = 100, // As Steve mentioned, you db must return this.
FriendName = "Friend 1"
};
friendRequest.Accepted += FriendRequest_Accepted;
friendRequest.Rejected += FriendRequest_Rejected;
flowLayoutPanel1.Controls.Add(friendRequest);
}
private void FriendRequest_Rejected(object sender, EventArgs e)
{
var friendRequest = sender as FriendRequestControl;
flowLayoutPanel1.Controls.Remove(friendRequest);
}
private void FriendRequest_Accepted(object sender, EventArgs e)
{
var friendRequest = sender as FriendRequestControl;
flowLayoutPanel1.Controls.Remove(friendRequest);
}