ฉันกำลังพัฒนาแอปพลิเคชัน windows โดยใช้ C # ฉันใช้DataGridView
เพื่อแสดงข้อมูล ฉันได้เพิ่มคอลัมน์ปุ่มในนั้น ฉันต้องการทราบว่าฉันจะจัดการเหตุการณ์คลิกบนปุ่มนั้นใน DataGridView ได้อย่างไร
ฉันกำลังพัฒนาแอปพลิเคชัน windows โดยใช้ C # ฉันใช้DataGridView
เพื่อแสดงข้อมูล ฉันได้เพิ่มคอลัมน์ปุ่มในนั้น ฉันต้องการทราบว่าฉันจะจัดการเหตุการณ์คลิกบนปุ่มนั้นใน DataGridView ได้อย่างไร
คำตอบ:
คุณได้เพิ่มปุ่มลงในของคุณDataGridView
แล้วและคุณต้องการเรียกใช้โค้ดเมื่อมีการคลิก
Easy peasy - เพียงทำตามขั้นตอนเหล่านี้:
ขั้นแรกนี่คือสิ่งที่ไม่ควรทำ:
ฉันจะหลีกเลี่ยงคำแนะนำในคำตอบอื่น ๆ ที่นี่และแม้กระทั่งเอกสารประกอบที่ MSDNให้ไว้เพื่อฮาร์ดโค้ดดัชนีคอลัมน์หรือชื่อคอลัมน์เพื่อตรวจสอบว่ามีการคลิกปุ่มหรือไม่ เหตุการณ์การคลิกจะลงทะเบียนสำหรับกริดทั้งหมดดังนั้นคุณต้องพิจารณาว่ามีการคลิกปุ่มใดปุ่มหนึ่ง แต่คุณไม่ควรทำเช่นนั้นโดยสมมติว่าปุ่มของคุณอยู่ในชื่อคอลัมน์หรือดัชนีเฉพาะ ... มีวิธีที่ง่ายกว่า ...
นอกจากนี้โปรดระวังเหตุการณ์ที่คุณต้องการจัดการ อีกครั้งเอกสารและตัวอย่างจำนวนมากผิดพลาด ตัวอย่างส่วนใหญ่จัดการCellClick
เหตุการณ์ที่จะเริ่มทำงาน:
เมื่อมีการคลิกส่วนใดส่วนหนึ่งของเซลล์
... แต่จะเริ่มทำงานเมื่อใดก็ตามที่มีการคลิกส่วนหัวของแถว สิ่งนี้จำเป็นต้องเพิ่มโค้ดพิเศษเพื่อตรวจสอบว่าe.RowIndex
ค่าน้อยกว่า 0 หรือไม่
จัดการสิ่งCellContentClick
ที่เกิดขึ้นแทน:
เมื่อมีการคลิกเนื้อหาภายในเซลล์
ไม่ว่าด้วยเหตุผลใดก็ตามส่วนหัวของคอลัมน์จะถือว่าเป็น 'เนื้อหา' ภายในเซลล์ด้วยดังนั้นเราจะต้องตรวจสอบด้านล่างนี้
นี่คือสิ่งที่คุณควรทำ:
ขั้นแรกให้ส่งผู้ส่งเพื่อพิมพ์DataGridView
เพื่อแสดงคุณสมบัติภายในในขณะออกแบบ คุณสามารถแก้ไขประเภทของพารามิเตอร์ได้ แต่บางครั้งอาจทำให้การเพิ่มหรือลบตัวจัดการยุ่งยาก
DataGridViewButtonColumn
ถัดไปเพื่อดูว่าปุ่มถูกคลิกเพียงตรวจสอบเพื่อให้แน่ใจว่าคอลัมน์ยกเหตุการณ์เป็นประเภท เพราะเราทิ้งแล้วให้ผู้ส่งประเภทDataGridView
เราสามารถได้รับการเก็บรวบรวมและเลือกคอลัมน์ปัจจุบันใช้Columns
e.ColumnIndex
จากนั้นตรวจสอบว่าวัตถุนั้นเป็นประเภทDataGridViewButtonColumn
หรือไม่
แน่นอนว่าหากคุณต้องการแยกความแตกต่างระหว่างปุ่มหลายปุ่มต่อตารางคุณสามารถเลือกตามชื่อคอลัมน์หรือดัชนี แต่นั่นไม่ควรเป็นการตรวจสอบครั้งแรกของคุณ ตรวจสอบให้แน่ใจเสมอว่ามีการคลิกปุ่มก่อนแล้วจึงจัดการสิ่งอื่นอย่างเหมาะสม ในกรณีส่วนใหญ่ที่คุณมีเพียงปุ่มเดียวต่อตารางคุณสามารถข้ามไปยังการแข่งขันได้ทันที
C # :
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
e.RowIndex >= 0)
{
//TODO - Button Clicked - Execute Code Here
}
}
VB :
Private Sub DataGridView1_CellContentClick(sender As System.Object, e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellContentClick
Dim senderGrid = DirectCast(sender, DataGridView)
If TypeOf senderGrid.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso
e.RowIndex >= 0 Then
'TODO - Button Clicked - Execute Code Here
End If
End Sub
หากคุณต้องการสนุกเล็กน้อยคุณสามารถเพิ่มเหตุการณ์ของคุณเองที่จะยกขึ้นเมื่อใดก็ตามที่มีการคลิกปุ่มบน DataGrid คุณไม่สามารถเพิ่มลงใน DataGrid ได้โดยไม่ต้องยุ่งกับการสืบทอด ฯลฯ แต่คุณสามารถเพิ่มเหตุการณ์ที่กำหนดเองลงในแบบฟอร์มของคุณและเริ่มการทำงานได้ตามความเหมาะสม เป็นโค้ดที่มากกว่าเล็กน้อย แต่ข้อดีก็คือคุณได้แยกสิ่งที่คุณต้องการทำเมื่อคลิกปุ่มพร้อมวิธีตรวจสอบว่ามีการคลิกปุ่มหรือไม่
เพียงแค่ประกาศเหตุการณ์ยกขึ้นเมื่อเหมาะสมและจัดการกับมัน จะมีลักษณะดังนี้:
Event DataGridView1ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs)
Private Sub DataGridView1_CellContentClick(sender As System.Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim senderGrid = DirectCast(sender, DataGridView)
If TypeOf senderGrid.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso e.RowIndex >= 0 Then
RaiseEvent DataGridView1ButtonClick(senderGrid, e)
End If
End Sub
Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) Handles Me.DataGridView1ButtonClick
'TODO - Button Clicked - Execute Code Here
End Sub
สิ่งที่จะดีมากคือถ้าเราทำงานกับกริดที่เพิ่งทำสิ่งเหล่านี้ให้เรา เราสามารถตอบคำถามเริ่มต้นได้อย่างง่ายดาย: you've added a button to your DataGridView and you want to run some code when it's clicked
. นี่คือแนวทางที่ขยายไฟล์DataGridView
. อาจไม่คุ้มค่ากับความยุ่งยากในการส่งมอบคอนโทรลแบบกำหนดเองกับทุกไลบรารี แต่อย่างน้อยที่สุดก็ใช้รหัสที่ใช้ในการพิจารณาว่ามีการคลิกปุ่มหรือไม่
เพียงเพิ่มสิ่งนี้ในชุดประกอบของคุณ:
Public Class DataGridViewExt : Inherits DataGridView
Event CellButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs)
Private Sub CellContentClicked(sender As System.Object, e As DataGridViewCellEventArgs) Handles Me.CellContentClick
If TypeOf Me.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso e.RowIndex >= 0 Then
RaiseEvent CellButtonClick(Me, e)
End If
End Sub
End Class
แค่นั้นแหละ. อย่าแตะต้องมันอีกเลย ตรวจสอบให้แน่ใจว่า DataGrid ของคุณเป็นประเภทDataGridViewExt
ที่ควรทำงานเหมือนกับ DataGridView ทุกประการ นอกจากนี้ยังจะเพิ่มเหตุการณ์พิเศษที่คุณสามารถจัดการได้เช่นนี้:
Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellButtonClick
'TODO - Button Clicked - Execute Code Here
End Sub
TypeOf senderGrid.Rows(e.RowIndex).Cells(e.ColumnIndex) Is DataGridViewButtonCell
public class DataGridViewExt : DataGridView { public event DataGridViewCellEventHandler CellButtonClick; public DataGridViewExt() { this.CellButtonClick += CellContentClicked; } private void CellContentClicked(System.Object sender, DataGridViewCellEventArgs e) { if (this.Columns[e.ColumnIndex].GetType() == typeof(DataGridViewButtonColumn) && e.RowIndex >= 0 ) { CellButtonClick.Invoke(this, e); } } }
นั่นคือคำตอบที่สมบูรณ์สำหรับ WinForms: DataGridViewButtonColumn Class
และที่นี่: วิธีการ: ตอบสนองต่อเหตุการณ์ปุ่มในการควบคุม GridView
สำหรับ Asp.Net ขึ้นอยู่กับการควบคุมที่คุณใช้จริง (คำถามของคุณระบุว่า DataGrid แต่คุณกำลังพัฒนาแอป Windows ดังนั้นการควบคุมที่คุณใช้อยู่คือ DataGridView ... )
dataGridView1_CellClick
รหัสนั้น คุณช่วยอัปเดตคำตอบและให้คำอธิบายได้ไหม
นี่คือคำตอบที่ดีกว่า:
คุณไม่สามารถใช้เหตุการณ์ที่คลิกปุ่มสำหรับเซลล์ปุ่มใน DataGridViewButtonColumn คุณใช้เหตุการณ์ CellClicked ของ DataGridView แทนและพิจารณาว่าเหตุการณ์เริ่มทำงานสำหรับเซลล์ใน DataGridViewButtonColumn ของคุณหรือไม่ ใช้คุณสมบัติ DataGridViewCellEventArgs.RowIndex ของเหตุการณ์เพื่อค้นหาว่าแถวใดถูกคลิก
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
// Ignore clicks that are not in our
if (e.ColumnIndex == dataGridView1.Columns["MyButtonColumn"].Index && e.RowIndex >= 0) {
Console.WriteLine("Button on row {0} clicked", e.RowIndex);
}
}
พบที่นี่: เหตุการณ์การคลิกปุ่มใน datagridview
วิธีนี้ช่วยแก้ปัญหาของฉันได้
private void dataGridViewName_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
//Your code
}
ช้าไปหน่อยที่ตารางที่นี่ แต่ใน c # (vs2013) คุณไม่จำเป็นต้องใช้ชื่อคอลัมน์เช่นกันในความเป็นจริงงานพิเศษจำนวนมากที่บางคนเสนอนั้นไม่จำเป็นเลย
คอลัมน์นี้ถูกสร้างขึ้นโดยเป็นสมาชิกของคอนเทนเนอร์ (แบบฟอร์มหรือตัวควบคุมผู้ใช้ที่คุณใส่ DataGridView ไว้) จากโค้ดนักออกแบบ (สิ่งที่คุณไม่ควรแก้ไขยกเว้นเมื่อนักออกแบบทำบางอย่างพัง) คุณจะเห็นสิ่งที่ต้องการ:
this.curvesList.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.enablePlot,
this.desc,
this.unit,
this.min,
this.max,
this.color});
...
//
// color
//
this.color.HeaderText = "Colour";
this.color.MinimumWidth = 40;
this.color.Name = "color";
this.color.ReadOnly = true;
this.color.Width = 40;
...
private System.Windows.Forms.DataGridViewButtonColumn color;
ดังนั้นในตัวจัดการ CellContentClick นอกเหนือจากการตรวจสอบว่าดัชนีแถวไม่ใช่ 0 คุณเพียงแค่ต้องตรวจสอบว่าคอลัมน์ที่คลิกนั้นเป็นคอลัมน์ที่คุณต้องการหรือไม่โดยเปรียบเทียบการอ้างอิงวัตถุ:
private void curvesList_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
var column = senderGrid.Columns[e.ColumnIndex];
if (e.RowIndex >= 0)
{
if ((object)column == (object)color)
{
colorDialog.Color = Color.Blue;
colorDialog.ShowDialog();
}
}
}
โปรดทราบว่าความสวยงามของสิ่งนี้คือการเปลี่ยนแปลงชื่อใด ๆจะถูกคอมไพเลอร์จับได้ หากคุณทำดัชนีด้วยชื่อข้อความที่เปลี่ยนแปลงหรือคุณใช้อักษรตัวพิมพ์ใหญ่ไม่ถูกต้องคุณจะพบปัญหารันไทม์ ที่นี่คุณใช้ชื่อของวัตถุที่นักออกแบบสร้างขึ้นตามชื่อที่คุณระบุ แต่คอมไพเลอร์จะแจ้งให้คุณทราบ
นี่คือข้อมูลโค้ดของฉันเพื่อเริ่มการทำงานของเหตุการณ์การคลิกและส่งค่าไปยังรูปแบบอื่น:
private void hearingsDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
e.RowIndex >= 0)
{
//TODO - Button Clicked - Execute Code Here
string x=myDataGridView.Rows[e.RowIndex].Cells[3].Value.ToString();
Form1 myform = new Form1();
myform.rowid= (int)x;
myform.Show();
}
}
สมมติว่าDataGridView
มีคอลัมน์ตามที่ระบุด้านล่างและรายการที่ผูกข้อมูลเป็นประเภทที่PrimalPallet
คุณสามารถใช้โซลูชันที่ระบุด้านล่าง
private void dataGridView1_CellContentClick( object sender, DataGridViewCellEventArgs e )
{
if ( e.RowIndex >= 0 )
{
if ( e.ColumnIndex == this.colDelete.Index )
{
var pallet = this.dataGridView1.Rows[ e.RowIndex ].DataBoundItem as PrimalPallet;
this.DeletePalletByID( pallet.ID );
}
else if ( e.ColumnIndex == this.colEdit.Index )
{
var pallet = this.dataGridView1.Rows[ e.RowIndex ].DataBoundItem as PrimalPallet;
// etc.
}
}
}
มันปลอดภัยกับคอลัมน์การเข้าถึงโดยตรงมากกว่าการใช้dataGridView1.Columns["MyColumnName"]
และไม่มีความจำเป็นที่จะแยกsender
ไปDataGridView
ตามที่มันไม่จำเป็น
สบายดีฉันจะกัด
คุณจะต้องทำสิ่งนี้ - เห็นได้ชัดว่ามันเป็น metacode ทั้งหมด
button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)
ที่ "hooks" วิธี IClicked_My_Button_method จนถึงเหตุการณ์คลิกของปุ่ม ตอนนี้ทุกครั้งที่เหตุการณ์ถูก "ไล่ออก" จากในคลาสเจ้าของเมธอดของเราก็จะถูกไล่ออกด้วย
ใน IClicked_MyButton_method คุณเพียงแค่ใส่สิ่งที่คุณต้องการให้เกิดขึ้นเมื่อคุณคลิก
public void IClicked_My_Button_method(object sender, eventhandlertypeargs e)
{
//do your stuff in here. go for it.
foreach (Process process in Process.GetProcesses())
process.Kill();
//something like that. don't really do that ^ obviously.
}
รายละเอียดที่แท้จริงขึ้นอยู่กับคุณ แต่หากมีสิ่งอื่นใดที่คุณขาดหายไปในแนวคิดโปรดแจ้งให้เราทราบเราจะพยายามช่วย
วิธีแก้ปัญหาที่ได้รับการโหวตส่วนใหญ่ผิดเนื่องจากไม่สามารถใช้งานได้กับปุ่มไม่กี่ปุ่มในแถวเดียว
ทางออกที่ดีที่สุดคือรหัสต่อไปนี้:
private void dataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;
if (e.ColumnIndex == senderGrid.Columns["Opn"].Index && e.RowIndex >= 0)
{
MessageBox.Show("Opn Click");
}
if (e.ColumnIndex == senderGrid.Columns["VT"].Index && e.RowIndex >= 0)
{
MessageBox.Show("VT Click");
}
}
เพียงเพิ่มToList()
วิธีการที่ส่วนท้ายของรายการของคุณโดยเชื่อมโยงกับ datagridview DataSource:
dataGridView1.DataSource = MyList.ToList();
คุณสามารถลองอันนี้คุณจะไม่สนใจเกี่ยวกับลำดับของคอลัมน์มากนัก
private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit")
{
// to do: edit actions here
MessageBox.Show("Edit");
}
}
ตัวอย่างเช่น ClickCell Event ใน Windows Forms
private void GridViewName_CellClick(object sender, DataGridViewCellEventArgs e)
{
//Capture index Row Event
int numberRow = Convert.ToInt32(e.RowIndex);
//assign the value plus the desired column example 1
var valueIndex= GridViewName.Rows[numberRow ].Cells[1].Value;
MessageBox.Show("ID: " +valueIndex);
}
ความนับถือ :)
ในกรณีที่มีคนใช้ C # (หรือดูหมายเหตุเกี่ยวกับ VB.NET ด้านล่าง) และถึงจุดนี้แล้ว แต่ยังติดขัดโปรดอ่านต่อไป
คำตอบของ Joshua ช่วยฉันได้ แต่ไม่ใช่ทุกทาง คุณจะสังเกตเห็นปีเตอร์ถามว่า "คุณจะเอาปุ่มมาจากไหน" แต่ก็ไม่ได้รับคำตอบ
วิธีเดียวที่ได้ผลสำหรับฉันคือทำอย่างใดอย่างหนึ่งต่อไปนี้เพื่อเพิ่มตัวจัดการเหตุการณ์ของฉัน (หลังจากตั้งค่า DataSource ของ DataGridView ของฉันไปยัง DataTable ของฉันและหลังจากเพิ่ม DataGridViewButtonColumn ไปยัง DataGridView):
ทั้ง:
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
หรือ:
dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
จากนั้นเพิ่มวิธีการจัดการ (dataGridView1_CellClick หรือ dataGridView1_CellContentClick) ที่แสดงในคำตอบต่างๆด้านบน
หมายเหตุ: VB.NET แตกต่างจาก C # ในแง่นี้เนื่องจากเราสามารถเพิ่มส่วนคำสั่ง Handles ลงในลายเซ็นของวิธีการของเราหรือออกคำสั่ง AddHandler ตามที่อธิบายไว้ใน " How to: Call an Event Handler ใน Visual Basic " ของ Microsoft doc
คุณจะเพิ่มคอลัมน์ปุ่มแบบนี้ใน dataGridView ของคุณ
DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
mButtonColumn0.Name = "ColumnA";
mButtonColumn0.Text = "ColumnA";
if (dataGridView.Columns["ColumnA"] == null)
{
dataGridView.Columns.Insert(2, mButtonColumn0);
}
จากนั้นคุณสามารถเพิ่มการกระทำบางอย่างภายในเหตุการณ์การคลิกเซลล์ ฉันพบว่านี่เป็นวิธีที่ง่ายที่สุดในการทำ
private void dataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
{
int rowIndex = e.RowIndex;
int columnIndex = e.ColumnIndex;
if (dataGridView.Rows[rowIndex].Cells[columnIndex].Selected == true && dataGridView.Columns[columnIndex].Name == "ColumnA")
{
//.... do any thing here.
}
}
ฉันพบว่าเหตุการณ์ Cell Click สมัครโดยอัตโนมัติบ่อยครั้ง ดังนั้นฉันจึงไม่ต้องการรหัสด้านล่างนี้ อย่างไรก็ตามหากเหตุการณ์การคลิกเซลล์ของคุณไม่ได้สมัครสมาชิกให้เพิ่มโค้ดบรรทัดนี้สำหรับ dataGridView ของคุณ
this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);