我有一个DataGridView
对象:
dataGridView1.DataSource = an.peaks;
(an.peaks是List<Point>
个对象。Point
类型有3个属性:x,y,z)
女巫在运行时生成下一个表:(显然我无法上传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] <==/
我想在满足某些条件的每一行的新列中添加按钮(如图像/图中所示)。如果条件不满意,请添加一些文字。
示例:如果数据库中已存在该点,则显示其物质名称(每个点代表一种物质)。如果没有将“ADD”按钮添加到将新点添加到数据库的相应行。
条件不是问题 - 它们仅用于示例。问题是向每行添加按钮/文本,为新按钮添加单击事件。
答案 0 :(得分:15)
使用DataGridView
实际上很简单。你需要做的是:
DataGridViewButtonColumn
是标准DataGridView
列类型。它可以通过设计器添加,但我通常更喜欢使用代码(通常在表单构造函数中)。
DataGridViewButtonColumn col = new DataGridViewButtonColumn();
col.UseColumnTextForButtonValue = True;
col.Text = "ADD";
col.Name = "MyButton";
dataGridView1.Columns.Add(col);
将UseColumnTextForButtonValue
设置为true表示Text
属性应用于所有按钮,为其提供“ADD”按钮文本。您还可以使用DataPropertyName
指向网格数据源中的列以提供按钮文本,或者甚至可以直接设置每个单元格的值。
获得按钮列后,您需要将特定按钮转换为文本。您可以通过将按钮类型的单元格替换为文本类型之一来完成此操作。你可以做很多这样的地方,但最好的地方之一就是DataBindingComplete
事件处理程序 - 一旦网格被绑定并准备好显示但是在它被绘制之前,这个事件就会触发。
下面我只需抓住索引为1的行,但您也可以检查每行Value
属性。
void dataGridView1_DataBindingComplete(object sender,
DataGridViewBindingCompleteEventArgs e)
{
dataGridView1.Rows[1].Cells["MyButton"] = new DataGridViewTextBoxCell();
}
问题的最后一部分是响应按钮点击。这有点笨拙 - 您需要对整个网格使用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!
}
在您的情况下,编辑控制方法可能是最好的,因为它不会响应单击已被文本替换的按钮。这种方式更像是您对表单上任何其他按钮的响应方式。
答案 1 :(得分:0)
您可以将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方式更容易。