C# 将新列中的按钮添加到 DataGrid 中的所有行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10769316/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add a button in a new column to all rows in a DataGrid
提问by Igor
I have a DataGridViewobject:
我有一个DataGridView对象:
dataGridView1.DataSource = an.peaks;
(an.peaks is a List<Point>object. Pointtype has 3 properties: x,y,z)
(an.peaks 是一个List<Point>对象。typePoint有 3 个属性:x,y,z)
witch generates the next table on run-time: (Apparently I cant upload an Imageyet because I'm a new user so I'll try to draw it :)
女巫在运行时生成下一个表:(显然我还不能上传,Image因为我是新用户,所以我会尝试绘制它:)
____|_x__|_y__|_z__|[new column ]
____|_11_|_12_|_13_|[text/button] <==\
____|_20_|_30_|_40_|[text/button] <== } Add text if something or button if something else.
____|_50_|_60_|_70_|[text/button] <==/
I would like to add buttons (as shown in the image/drawing) in a new column to each row that satisfying some condition. If the condition is not satisfied add some text instead.
我想在新列中为满足某些条件的每一行添加按钮(如图像/绘图所示)。如果不满足条件,请添加一些文本。
Example: If the point already exist in the database show it's substance name (each point represent a substance). If not add a button "ADD" to the corresponding row that will add the new point to the database.
示例:如果数据库中已存在该点,则显示其物质名称(每个点代表一种物质)。如果没有在相应的行中添加一个按钮“添加”,则将新点添加到数据库中。
The conditions are not the problems - they are only for examples. The problem is adding the buttons/text to each row and the clicking event for the new button/s.
条件不是问题 - 它们仅用于示例。问题是将按钮/文本添加到每一行以及新按钮的点击事件。
采纳答案by David Hall
This is actually quite simple to do using the DataGridView. What you need to do is:
使用DataGridView. 你需要做的是:
Add column of type DataGridViewButtonColumn
添加 DataGridViewButtonColumn 类型的列
DataGridViewButtonColumnis a standard DataGridViewcolumn type. It can be added through the designer but I generally prefer using code (usually in the form constructor).
DataGridViewButtonColumn是标准DataGridView列类型。它可以通过设计器添加,但我通常更喜欢使用代码(通常在表单构造函数中)。
DataGridViewButtonColumn col = new DataGridViewButtonColumn();
col.UseColumnTextForButtonValue = True;
col.Text = "ADD";
col.Name = "MyButton";
dataGridView1.Columns.Add(col);
Setting UseColumnTextForButtonValuetrue means that the Textproperty gets applied to all buttons giving them the "ADD" button text. You can also use DataPropertyNameto point at a column in the grid's datasource to provide the button text, or you can even set each cell's value directly.
设置UseColumnTextForButtonValuetrue 意味着该Text属性将应用于所有按钮,为它们提供“添加”按钮文本。您还可以使用DataPropertyName指向网格数据源中的列来提供按钮文本,或者您甚至可以直接设置每个单元格的值。
Change buttons to text
将按钮更改为文本
Once you have your button column you then want to turn particular buttons to text. You do this by replacing a cell of button type with one of text type. You can do this many places but one of the best is in the DataBindingCompleteevent handler - this event fires once the grid is bound and ready to display but before it is painted.
一旦你有你的按钮列,你就想把特定的按钮变成文本。您可以通过将按钮类型的单元格替换为文本类型之一来完成此操作。您可以在很多地方执行此操作,但最好的方法之一是在DataBindingComplete事件处理程序中 - 一旦网格绑定并准备好显示但在绘制之前触发此事件。
Below I simply grab the row with index 1 but you can also inspect each rows Valueproperty.
下面我只是抓取索引为 1 的行,但您也可以检查每个行Value属性。
void dataGridView1_DataBindingComplete(object sender,
DataGridViewBindingCompleteEventArgs e)
{
dataGridView1.Rows[1].Cells["MyButton"] = new DataGridViewTextBoxCell();
}
Respond to button clicks
响应按钮点击
The final part of the problem is responding to button clicks. This is a little bit cludgy - you need to either use the CellClickevent or the EditingControlShowingevent for the entire grid.
问题的最后一部分是响应按钮点击。这有点笨拙 - 您需要为整个网格使用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! }
单元格点击
private void DataGridView1_CellClick(object sender, System.Windows.FormsDataGridViewCellEventArgs e) { if (DataGridView1.Columns[e.ColumnIndex].Name == "MyButton") { // button clicked - do some logic } }编辑控件显示
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! }
In your case the editing control approach is probably best since it won't respond to clicking on buttons that have been replaced with text. Also this way is more like how you respond to any other button on a form.
在您的情况下,编辑控件方法可能是最好的,因为它不会响应单击已被文本替换的按钮。此外,这种方式更像是您如何响应表单上的任何其他按钮。
回答by Unril
You can add WPF host controlto WinForms project and use DataGrid with CellTemplateSelector. For example:
您可以将WPF 主机控件添加到 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>
And selector class:
和选择器类:
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;
}
}
It may by easier than WinForms way.
它可能比 WinForms 方式更容易。

