Добавить кнопку в новый столбец ко всем строкам в DataGrid

у меня есть

2 ответов


это на самом деле довольно просто сделать с помощью DataGridView. Что вам нужно сделать, это:

добавить столбец типа DataGridViewButtonColumn

DataGridViewButtonColumn стандартная DataGridView тип столбца. Его можно добавить через конструктор, но я обычно предпочитаю использовать код (обычно в конструкторе формы).

DataGridViewButtonColumn col = new DataGridViewButtonColumn();
col.UseColumnTextForButtonValue = True;
col.Text = "ADD";
col.Name = "MyButton";
dataGridView1.Columns.Add(col);

задание UseColumnTextForButtonValue true означает, что Text свойство применяется ко всем кнопкам, давая им текст кнопки "Добавить". Вы можете также используйте DataPropertyName чтобы указать на столбец в источнике данных сетки, чтобы предоставить текст кнопки, или вы даже можете установить значение каждой ячейки напрямую.

изменить кнопки на текст

как только у вас есть столбец кнопки, вы хотите превратить определенные кнопки в текст. Это можно сделать, заменив ячейку типа button на ячейку типа text. Вы можете сделать это во многих местах, но один из лучших находится в DataBindingComplete обработчик событий-это событие срабатывает, как только сетка привязана и готова к отображению но перед тем, как его покрасить.

ниже я просто хватаю строку с индексом 1, но вы также можете проверить каждую строку Value собственность.

void dataGridView1_DataBindingComplete(object sender,
    DataGridViewBindingCompleteEventArgs e)
{
    dataGridView1.Rows[1].Cells["MyButton"] = new DataGridViewTextBoxCell();
}

ответить на щелчки кнопки

заключительная часть проблемы отвечает на щелчки кнопок. Это немного cludgy - вам нужно использовать CellClick или EditingControlShowing событие для всей сетка.

  • CellClick

    private void DataGridView1_CellClick(object sender,
        System.Windows.FormsDataGridViewCellEventArgs e) 
    { 
        if (DataGridView1.Columns[e.ColumnIndex].Name == "MyButton") 
        { 
            // button clicked - do some logic
        } 
    }
    
  • EditingControlShowing

    void dataGridView1_EditingControlShowing(object sender,
         DataGridViewEditingControlShowingEventArgs e)
    {
        if (e.Control is Button)
        {
            Button btn = e.Control as Button;
            btn.Click -= new EventHandler(btn_Click);
            btn.Click += new EventHandler(btn_Click);
        }
    }
    
    void btn_Click(object sender, EventArgs e)
    {
        int col = this.dataGridView1.CurrentCell.ColumnIndex;
        int row = this.dataGridView1.CurrentCell.RowIndex;
        // Rest of the logic goes here!
    } 
    

в вашем случае подход управления редактированием, вероятно, лучше, так как он не будет реагировать на нажатие на кнопки, которые были заменены текстом. Также Этот способ больше похож на то, как вы реагируете на любую другую кнопку в форме.


Вы можете добавить WPF host control для проекта WinForms и использования DataGrid с CellTemplateSelector. Например:

<DataGrid x:Name="grid" AutoGenerateColumns="False" x:FieldModifier="private">
  <DataGrid.Resources>
    <local:PointDataTemplateSelector x:Key="pointDataTemplateSelector" />
    <DataTemplate x:Key="buttonTemplate">
      <Button Click="OnAddButtonClick" Tag="{Binding Mode=OneWay}">Add</Button>
    </DataTemplate>
    <DataTemplate x:Key="textTemplate">
      <TextBlock>Exists</TextBlock>
    </DataTemplate>
  </DataGrid.Resources>
  <DataGrid.Columns>
    <DataGridTextColumn Header="X" Binding="{Binding X}" />
    <DataGridTextColumn Header="Y" Binding="{Binding Y}" />
    <DataGridTemplateColumn Header="Select" CellTemplateSelector="{StaticResource pointDataTemplateSelector}"></DataGridTemplateColumn>
  </DataGrid.Columns>
</DataGrid>

и селектор класса:

public class PointDataTemplateSelector : DataTemplateSelector {
    public override DataTemplate SelectTemplate(object item, DependencyObject container) {
        var element = container as FrameworkElement;
        if (element != null && item != null && item is Point) {
            var point = (Point)item;

            // Logic here.
            if (point.X >= 5) {
                return element.FindResource("buttonTemplate") as DataTemplate;
            }
            return element.FindResource("textTemplate") as DataTemplate;
        }

        return null;
    }
}

это может быть проще, чем WinForms.