【问题标题】:DataGridView DataGridViewButtonColumn doesn't notice a real ButtonDataGridView DataGridViewButtonColumn 没有注意到真正的 Button
【发布时间】:2014-09-24 21:05:52
【问题描述】:

感谢您查看我的问题。我有一个名为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 对象时,它似乎没有“注意到”或“关心”我给它一个按钮.. 我如何让DataGridView 关心我已经发给它需要的Buttons

【问题讨论】:

    标签: c# winforms button datagridview datagridviewbuttoncolumn


    【解决方案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);
       }
    
    }
    

    这是获取按钮事件处理程序的修改代码:

    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,他们添加了控件而不是组件的更改..

    编辑 我注意到按钮栏没有文字。要显示单个按钮的文本,您需要像这样编写DataGridView_CellFormattingevent:

    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 而只是显示的文本。

    【讨论】:

      【解决方案2】:

      感谢您的回答,由于是周末和下班,我实际上在发布后 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***
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-25
        • 1970-01-01
        • 1970-01-01
        • 2023-01-30
        • 1970-01-01
        相关资源
        最近更新 更多