【问题标题】:Change all buttons on a form更改表单上的所有按钮
【发布时间】:2011-08-13 06:36:13
【问题描述】:

我已经非常接近找到解决这个问题的方法了;在这一点上只是漏掉了一个小细节。

我想做什么:
我想通过代码更改表单(Form1)上每个按钮的光标样式。我知道如何使用 foreach 搜索表单上的所有控件,但我不确定如何通过我编写的例程将此控件作为参数传递。我将在下面展示我正在执行的操作的示例。

private void Form1_Load(object sender, EventArgs e)
{
    foreach (Button b in this.Controls)
    {
        ChangeCursor(b);  // Here is where I'm trying to pass the button as a parameter.  Clearly this is not acceptable.
    }     
}

private void ChangeCursor(System.Windows.Forms.Button Btn)
{
    Btn.Cursor = Cursors.Hand;
}

有人可以给我小费吗?

非常感谢

埃文

【问题讨论】:

    标签: c# winforms button controls


    【解决方案1】:

    这对我来说是正确的;有没有我没看到的问题?

    编辑:啊是的 - 如果集合中有非按钮控件,则转换将失败。

    您只想传入 按钮的控件,因此您需要添加一个 IF 语句。

    【讨论】:

    • 是的,调试模式下的 Visual Studio 突出显示“按钮 b”并说 -“无法将类型为 'System.Windows.Forms.TabControl' 的对象转换为类型 'System.Windows.Forms.Button' 。”
    • 不太正确,表单上的控件可以不仅仅是按钮。
    • -1:仅当Form 仅包含Button 控件时才正确。
    • 问题是,'但我不确定如何通过我编写的例程将此控件作为参数传递'。他的代码成功地做到了。是的,非按钮控件可能会导致运行时错误,但这不是问题的一部分。
    【解决方案2】:

    改变

    foreach (Button b in this.Controls)
    {
        ChangeCursor(b);  // Here is where I'm trying to pass the button as a parameter.
                          // Clearly this is not acceptable.
    }     
    

    foreach (Control c in this.Controls)
    {
       if (c is Button)
       {
            ChangeCursor((Button)c);  
       }
    }  
    

    并非表单上的每个控件都是按钮。

    编辑:您还应该寻找嵌套控件。请参阅 Bala R. 的答案。

    【讨论】:

    • 此外,并非表单上的每个控件都是表单的直接子项。这种方法不包括孩子的孩子。
    • 我发现了问题:这只是在搜索我的 TAB 控件!不是我的表格!
    【解决方案3】:

    如果您的任何控件未能从按钮继承,我认为您的 foreach 将引发异常。

    试试这样的:

    foreach (Control b in this.Controls)
    {
    
      if (b is Button)
        ChangeCursor((Button)b);  
    }    
    

    【讨论】:

    • Russel - 虽然您上面的代码确实会引发任何异常,但它不会更改表单上的任何按钮。它不会在循环中的任何点通过“if (b is button)”。
    • 我必须相信你,Evan,因为我还没有编译它,但我不明白为什么会这样。
    • 顺便说一句 - 即使只有一行,最好将 foreach/if etc 块包裹在花括号中,因为它可以在以后节省编程错误 - 我只是懒惰。不过应该仍然可以工作。
    • @埃文。如果其中一个控件是 Button,那么它肯定会通过 if。
    【解决方案4】:

    我看到的唯一情况是,如果您有嵌套控件,this.Controls 不会拾取这些控件。你可以试试这个

    public IEnumerable<Control> GetSelfAndChildrenRecursive(Control parent)
    {
        List<Control> controls = new List<Control>();
    
        foreach(Control child in parent.Controls)
        {
            controls.AddRange(GetSelfAndChildrenRecursive(child));
        }
    
        controls.Add(parent);
    
        return controls;
    }
    

    然后打电话

    GetSelfAndChildrenRecursive(this).OfType<Button>.ToList()
                      .ForEach( b => b.Cursor = Cursors.Hand);
    

    【讨论】:

    • 我建议将GetSelfAndChildrenRecursive 设为通用方法并按特定类型过滤控件,例如:GetSelfAndChildrenRecursive&lt;Button&gt;(),而不是获取所有类型然后按特定类型过滤它们
    • @Homam 我将此函数用于我可能想要对 diff 类型的控件进行操作的其他目的(例如启用所有嵌套控件)。但是出于 OP 的目的,您的建议可能有效,但 OfType 仍然非常可读。
    • @Homam 我想我的回答 stackoverflow.com/a/42400534/1039753 可能已经接近你的想法了。
    • 我认为.OfType&lt;Button&gt;() 是正确的不是.OfType&lt;Button&gt; 根据这个:stackoverflow.com/q/44983056/4439444
    【解决方案5】:

    你也可以使用更简洁的语法:

    foreach (Control c in this.Controls)    
    {       
        if (c is Button)       
        {          
            ChangeCursor(c as Button);         
        }    
    } 
    

    【讨论】:

      【解决方案6】:

      与 Bala R 的答案相同,但我这样做的方式是......

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Windows.Forms;
      
      namespace AppName
      {
          public static class ControlExtensions
          {
              public static IEnumerable<Control> GetAllCtls(this Control control, Type type)
              {
                  var controls = control.Controls.Cast<Control>();
      
                  return controls.SelectMany(ctrl => GetAllCtls(ctrl, type))
                                            .Concat(controls)
                                            .Where(c => c.GetType() == type);
              }
          }
      }
      

      那就这样用吧……

      foreach (Control ctl in this.GetAllCtls(typeof(Button)))
      {
          MessageBox.Show("Found a button on the form called '" + ctl.Text + "'");
      }
      

      【讨论】:

        猜你喜欢
        • 2018-03-09
        • 2014-12-31
        • 2013-01-05
        • 1970-01-01
        • 1970-01-01
        • 2020-09-16
        • 2017-10-03
        • 2018-10-13
        • 1970-01-01
        相关资源
        最近更新 更多