Estou desenvolvendo um aplicativo Windows usando C #. Estou usando DataGridView
para exibir dados. Eu adicionei uma coluna de botão nisso. Quero saber como lidar com o evento click nesse botão no DataGridView.
Estou desenvolvendo um aplicativo Windows usando C #. Estou usando DataGridView
para exibir dados. Eu adicionei uma coluna de botão nisso. Quero saber como lidar com o evento click nesse botão no DataGridView.
Respostas:
Você adicionou um botão ao seu DataGridView
e deseja executar um código quando ele for clicado.
Fácil - basta seguir estes passos:
Primeiro, eis o que NÃO fazer:
Eu evitaria as sugestões em algumas das outras respostas aqui e até mesmo fornecidas pela documentação no MSDN para codificar o índice da coluna ou o nome da coluna para determinar se um botão foi clicado. O evento click é registrado para toda a grade, então, de alguma forma, você precisa determinar se um botão foi clicado, mas não deve fazê-lo assumindo que o botão esteja em um nome ou índice de coluna específico ... existe uma maneira mais fácil ...
Além disso, tenha cuidado com o evento que você deseja manipular. Novamente, a documentação e muitos exemplos entendem isso errado. A maioria dos exemplos manipula o CellClick
evento que será acionado:
quando qualquer parte de uma célula é clicada.
... mas também será acionado sempre que o cabeçalho da linha for clicado. Isso requer a adição de código extra simplesmente para determinar se o e.RowIndex
valor é menor que 0
Em vez disso, lide com o CellContentClick
que ocorre apenas:
quando o conteúdo de uma célula é clicado
Por qualquer motivo, o cabeçalho da coluna também é considerado 'conteúdo' dentro de uma célula, portanto, ainda precisamos verificar isso abaixo.
Então, aqui está o que você deve fazer:
Primeiro, transmita o remetente para digitar DataGridView
para expor suas propriedades internas em tempo de design. Você pode modificar o tipo no parâmetro, mas às vezes isso pode dificultar a adição ou remoção de manipuladores.
Em seguida, para ver se um botão foi clicado, verifique se a coluna que gera o evento é do tipo DataGridViewButtonColumn
. Como já convertemos o remetente para digitar DataGridView
, podemos obter a Columns
coleção e selecionar a coluna atual usando e.ColumnIndex
. Em seguida, verifique se esse objeto é do tipo DataGridViewButtonColumn
.
Obviamente, se você precisar distinguir entre vários botões por grade, poderá selecionar com base no nome ou índice da coluna, mas essa não deve ser sua primeira verificação. Sempre verifique se um botão foi clicado primeiro e depois lide com qualquer outra coisa de maneira apropriada. Na maioria dos casos em que você tem apenas um botão por grade, pode pular direto para as corridas.
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
Se você quiser se divertir um pouco, pode adicionar seu próprio evento a ser gerado sempre que um botão for clicado no DataGrid. Você não pode adicioná-lo ao próprio DataGrid, sem ficar com a herança, etc., mas pode adicionar um evento personalizado ao seu formulário e acioná-lo quando apropriado. É um pouco mais de código, mas o lado positivo é que você separou o que deseja fazer quando um botão é clicado e como determinar se um botão foi clicado.
Apenas declare um evento, crie-o quando apropriado e lide com ele. Isso parecerá assim:
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
O que seria ótimo é se estivéssemos trabalhando com uma grade que fez essas coisas por nós. Poderíamos responder à pergunta inicial facilmente: you've added a button to your DataGridView and you want to run some code when it's clicked
. Aqui está uma abordagem que estende o DataGridView
. Pode não valer a pena o trabalho de fornecer um controle personalizado a cada biblioteca, mas pelo menos reutiliza ao máximo o código usado para determinar se um botão foi clicado.
Basta adicionar isso à sua montagem:
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
É isso aí. Nunca toque novamente. Verifique se o seu DataGrid é do tipo DataGridViewExt
que deve funcionar exatamente da mesma forma que um DataGridView. Exceto que isso também gerará um evento extra com o qual você pode lidar assim:
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); } } }
Isso é totalmente respondido aqui para WinForms: DataGridViewButtonColumn Class
e aqui: Como: Responder a eventos de botão em um controle GridView
para Asp.Net, dependendo do controle que você está realmente usando. (Sua pergunta diz DataGrid, mas você está desenvolvendo um aplicativo do Windows, portanto, o controle que você usaria lá é um DataGridView ...)
dataGridView1_CellClick
nesse código. Você pode atualizar sua resposta e me fornecer uma descrição.
Aqui está a melhor resposta:
Você não pode implementar um evento clicado no botão para células de botão em um DataGridViewButtonColumn. Em vez disso, use o evento CellClicked do DataGridView e determine se o evento disparou para uma célula no seu DataGridViewButtonColumn. Use a propriedade DataGridViewCellEventArgs.RowIndex do evento para descobrir qual linha foi clicada.
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);
}
}
encontrado aqui: clique no evento do botão no datagridview
Um pouco atrasado para a tabela aqui, mas no c # (vs2013) você também não precisa usar nomes de colunas; na verdade, muito do trabalho extra que algumas pessoas propõem é completamente desnecessário.
A coluna é realmente criada como um membro do contêiner (o formulário ou controle de usuário no qual você colocou o DataGridView). No código do designer (as coisas que você não deve editar, exceto quando o designer quebra algo), você vê algo como:
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;
Portanto, no manipulador CellContentClick, além de garantir que o índice da linha não seja 0, basta verificar se a coluna clicada é realmente a que você deseja comparando as referências de objeto:
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();
}
}
}
Observe que a beleza disso é que qualquer alteração de nome será capturada pelo compilador. Se você indexar com um nome de texto que seja alterado ou maiúsculo incorretamente, estará sujeito a problemas de tempo de execução. Aqui você realmente usa o nome de um objeto que o designer cria com base no nome que você forneceu. Mas qualquer incompatibilidade será trazida à sua atenção pelo compilador.
Aqui está meu trecho de código para disparar o evento click e passar o valor para outro formulário:
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();
}
}
Supondo, por exemplo DataGridView
, que as colunas sejam fornecidas abaixo e seus itens vinculados a dados sejam do tipo, PrimalPallet
você pode usar a solução fornecida abaixo.
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.
}
}
}
É mais seguro acessar colunas diretamente, em vez de usar, dataGridView1.Columns["MyColumnName"]
e não há necessidade de analisar sender
as informações, DataGridView
pois elas não são necessárias.
bem, eu vou morder.
você precisará fazer algo assim - obviamente, é todo o metacódigo.
button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)
que "conecta" o método IClicked_My_Button_method ao evento Click do botão. Agora, toda vez que o evento for "disparado" de dentro da classe do proprietário, nosso método também será disparado.
No método IClicked_MyButton_, você coloca o que deseja que aconteça ao clicar nele.
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.
}
Os detalhes reais aqui são com você, mas se houver mais alguma coisa que estiver faltando conceitualmente, entre em contato e tentarei ajudar.
A solução mais votada está errada, pois não pode funcionar com poucos botões em uma linha.
A melhor solução será o seguinte código:
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");
}
}
basta adicionar o ToList()
método ao final da sua lista, onde vincular ao datagridview DataSource:
dataGridView1.DataSource = MyList.ToList();
Você pode tentar este, você não se importaria muito com a ordem das colunas.
private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit")
{
// to do: edit actions here
MessageBox.Show("Edit");
}
}
Por exemplo, para o ClickCell Event no 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);
}
Saudações :)
Caso alguém esteja usando C # (ou veja a Nota sobre o VB.NET abaixo) e tenha atingido esse ponto, mas ainda esteja parado, continue lendo.
A resposta de Joshua me ajudou, mas não o tempo todo. Você notará que Peter perguntou "De onde você tiraria o botão?", Mas ficou sem resposta.
A única maneira que funcionou para mim foi seguir um destes procedimentos para adicionar meu manipulador de eventos (depois de definir o DataSource do meu DataGridView ao meu DataTable e depois de adicionar o DataGridViewButtonColumn ao DataGridView):
Ou:
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
ou:
dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);
E adicione o método manipulador (dataGridView1_CellClick ou dataGridView1_CellContentClick) mostrado nas várias respostas acima.
Nota: O VB.NET é diferente do C # a esse respeito, porque podemos simplesmente adicionar uma cláusula Handles à assinatura do nosso método ou emitir uma instrução AddHandler conforme descrito no documento da Microsoft " Como: chamar um manipulador de eventos no Visual Basic "
Você adicionará uma coluna de botões como esta em seu dataGridView
DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
mButtonColumn0.Name = "ColumnA";
mButtonColumn0.Text = "ColumnA";
if (dataGridView.Columns["ColumnA"] == null)
{
dataGridView.Columns.Insert(2, mButtonColumn0);
}
Em seguida, você pode adicionar algumas ações dentro do evento de clique na célula. Eu achei que essa é a maneira mais fácil de fazer isso.
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.
}
}
Descobri que o evento Cell Click é automaticamente inscrito com frequência. Então, eu não precisava desse código abaixo. No entanto, se o evento de clique na célula não estiver inscrito, adicione esta linha de código ao seu dataGridView.
this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);