2016-06-21 84 views
1

我很努力地創建此腳本,它生成好友請求。我需要爲每個按鈕和標籤特別添加一個ID,以便在用戶單擊接受或拒絕按鈕時將其刪除。c#如何創建按鈕並稍後通過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##); 
+3

你可以得到該事件處理程序中的按鈕爲: 'Button buttonClicked = sender as Button'' –

+1

使用按鈕的Tag屬性。你可以用一些識別值來設置它(例如你的SQL查詢檢索到的一個ID)然後在按鈕單擊事件中,在將發件人參數強制轉換爲按鈕後,讀回該屬性 – Steve

+0

我還會提出一件事。 您應該擴展按鈕類。並使用另一個字段說「ID」。然後,當您將按鈕放置在表單上時,將相關值分配給該字段。在此之後,當您在點擊事件中取回按鈕時,您可以獲得該值。這是否有道理,讓我知道,我會發布整個解決方案。 –

回答

4

要做的第一件事情就是從您的查詢檢索唯一標識您的數據的價值。假設你PendingRequest表有一個IDRequest那麼你的查詢可以改爲

using (SqlCommand cmd = new SqlCommand(@"Select IDRequest, UserFirstName, 
         UserLastName, FriendEmail 
         From PendingRequests 
         Where FriendEmail = @fe", connection)) 

現在,當你動態創建控件,你還可以添加該ID來通過記錄創建的每個控件的Tag屬性

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集合移動控件,您不應該忘記將其丟棄。

+0

感謝您的回覆!我得到這個錯誤:http://oi68.tinypic.com/dbjy2s.jpg – richardj97

+0

修復它,.Cast 應該是一種方法 – richardj97

+0

偉大的作品,但它並沒有刪除'接受'按鈕..它刪除了'拒絕'按鈕和用戶名稱...? – richardj97

1

@Steve回答得很好。他已經向您展示瞭如何修復當前的代碼。

我想建議你一個更好的方式來構建你的當前代碼,以便它看起來更乾淨,並且你可以更好地控制好友請求功能。如果您有興趣,請進一步閱讀。如果你在緊迫的期限內,那麼忽略:)。

如果我在您的位置,我會創建一個用戶控件來表示個人好友請求,並在接受/拒絕時使用事件通知主窗體,以便它可以從面板/列表中刪除請求。通過這種方式,主表單代碼(設計器+後面的代碼)將變得更清晰,可以閱讀和理解。

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); 
}