感谢您查看我的问题。我有一个名为UIChoice
namespace uitest
{
public class UIChoice
{
public String name {get; set;}
public Button yes { get; set; }
}
}
然后我有Form1
DataGridView
(我称之为grdChoice
),就像这样
namespace uitest
{
public class Form1 : Form
{
public BindingList<UIChoice> Choices = new BindingList<UIChoice>();
public Form1 ()
{
InitializeComponent();
DataGridViewTextBoxColumn colName = new DataGridViewTextBoxColumn();
colName.HeaderText = "Name:";
colName.Name = "yestext";
colName.DataPropertyName = "name";
grdChoice.Columns.Add(colName);
DataGridViewButtonColumn colYes = new DataGridViewButtonColumn();
colYes.HeaderText = "Yes:";
colYes.Name = "yesbutton";
colYes.DataPropertyName = "yes";
colYes.FlatStyle = FlatStyle.Popup;
grdChoice.Columns.Add(colYes);
grdChoice.DataSource = Choices;
grdChoice.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
grdChoice.Show();
FillData();
}
private void FillData()
{
UIChoice myChoice = new UIChoice();
Button Yes = new Button();
Yes.Click += ((sender, args) =>
{
MessageBox.Show("try this yes works");
});
Yes.Text = "yes";
myChoice.name = "try this";
myChoice.yes = Yes;
Choices.Add(myChoice);
UIChoice myChoiceA = new UIChoice();
Button YesA = new Button();
YesA.Click += ((sender, args) =>
{
MessageBox.Show("try A yes works");
});
YesA.Text = "yes";
myChoiceA.name = "try A";
myChoiceA.yes = YesA;
Choices.Add(myChoiceA);
}
}
}
应该发生的事情(在我的想象中)是DataGridView
应该注意到它是DataGridViewButtonColumn
并且注意到它已经被给了一个按钮并使用它。但事实并非如此。对我来说问题是这是一个替代代码。在现实生活中,UIChoice
对象是用方法强化的,而DataGridView
(最初)仅仅是为了取代手动曲面的水平增量按钮(变得太“大”),悲伤的部分是正如我写的那样DataGridView
不起作用,即当我构造一个BindingList对象时,它似乎没有“注意到”或“关心”我给它一个按钮..我该怎么做{ {1}}关心我已经发送了它需要的DataGridView
吗?
答案 0 :(得分:1)
关闭。
按钮,希望是在细胞价值观中。
但是你不能像那样点击它们。
而是编码grdChoice.CellClick
事件,可能是这样的:
if (e.ColumnIndex == yourButtonColumnIndex )
{
Button btn = gradesDataGridView[yourButtonColumnIndex , e.RowIndex].Value as Button;
if (btn != null) buttons_Click(btn, null);
}
这将触发一个公共事件buttons_Click
,您可以使用sender参数来识别按钮并调用相应的代码。
这可能没关系,但也许您更愿意看到正确的点击会自动触发..?
使用一点反射魔法(在CodeProject上找到here),这也有效:
if (e.ColumnIndex == yourButtonColumnIndex )
{
Button btn = gradesDataGridView[yourButtonColumnIndex , e.RowIndex].Value as Button;
if (btn != null)
{
var handler = (EventHandler)GetDelegate(btn, "EventClick");
if (handler != null) btn.Invoke(handler);
}
}
以下是获取Buttons事件处理程序的修改代码:
private static object GetDelegate(Control issuer, string keyName)
{
// Get key value for a Click Event
var key = typeof(Control)
.GetField(keyName, BindingFlags.Static | BindingFlags.NonPublic |
BindingFlags.FlattenHierarchy)
.GetValue(null);
var events = typeof(Component)
.GetField("events", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(issuer);
// Find the Find method and use it to search up listEntry for corresponding key
var listEntry = typeof(EventHandlerList)
.GetMethod("Find", BindingFlags.NonPublic | BindingFlags.Instance)
.Invoke(events, new object[] { key });
// Get handler value from listEntry
var handler = listEntry
.GetType()
.GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(listEntry);
return handler;
}
向CodeProject上的人,Kostikov先生和匿名用户#2573523致敬,他们为Controls而不是Components添加了更改。
编辑我注意到按钮列没有文字。要显示各个按钮&#39;您需要为DataGridView_CellFormatting
事件编码的文本,如下所示:
private void gradesDataGridView_CellFormatting(
object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == yourBottonColumnIndex )
{
Button btn = gradesDataGridView[yourButtonColumnIndex , e.RowIndex].Value as Button;
if (btn != null) e.Value = btn.Text;
}
}
请注意,e.Value不是cell.Value,只是显示的文本。
答案 1 :(得分:1)
谢谢你的回答,作为周末和工作之余,我在发布后的4小时内完成了这个,但是等了8个小时 - 不过你会得到积分! :-)(我也借用了按钮文本显示的e.value
部分,因为它比我的更优雅!)
好吧,我个人,我通过意识到DataGridView
CellClick (DataGridView sender).CurrentCell.Value
实际上是(Button)
来修复它。这就是我这样做的方法:(稍微阅读OP并调整Form1
构造函数的底部):
grdChoice.DataSource = Verdicts;
grdChoice.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
grdChoice.CellClick += grdChoice_CellClick; //<-- add this line ***
grdChoice.Show();
下一部分只是观察任何单元格上的任何点击,如果它是一个按钮列,人为地点击按钮“内部”按钮
private void grdChoice_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == grdChoice.Columns["yesbutton"].Index)
{
((Button)((DataGridView)sender).CurrentCell.Value).PerformClick();
}
}
最后一部分是显示我所做的按钮文本:
private void grdVerdict_CellFormat(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == grdChoice.Columns["yesbutton"].Index)
{
e.Value = ((Button)grdChoice[e.ColumnIndex, e.RowIndex].Value).Text;
}
}
使用此处理程序
grdVerdict.CellFormatting += grdVerdict_CellFormat; //<-- add this line near where the 3 stars are above***