代码之家  ›  专栏  ›  技术社区  ›  B. Clay Shannon-B. Crow Raven

是否有LINQy方法将所有ReadOnly控件的TabStop设置为false?

  •  -1
  • B. Clay Shannon-B. Crow Raven  · 技术社区  · 11 年前

    我使用以下代码将ReadOnly属性为true的所有控件的TabStop属性设置为false:

    foreach (Control control in this.Controls)
    {
        if (control is TextBox)
        {
            //if (((TextBox)control).ReadOnly)
            //{
            //    control.TabStop = false;
            //}
            control.TabStop = (!((TextBox)control).ReadOnly);
        }
    }
    

    …但我认为可能有一种更“现代”(优雅/花哨)的方式来实现这一点,可能是LINQ。

    更新

    好的,所以我认为,根据答案,这会奏效:

    private void FrmDelivery_Load(object sender, EventArgs e)
    {
        var q = Controls.SelectMany(c => Walk(c)).OfType<TextBox>().Where(c 
    => c.ReadOnly);
        foreach (var control in q)
        {
            control.TabStop = false;
        }
    }
    
    IEnumerable<Control> Walk(Control control)
    {
        yield return control;
        foreach (var child in control.Controls.SelectMany(c=> Walk(c)))
        {
            yield return c;
        }
    }
    

    …但我得到:

    " “System.Windows.Forms.Control.ControlCollection”不包含“SelectMany”的定义,并且找不到接受“System.Windows.Vorms.ControlControlCollection”类型的第一个参数的扩展方法“SelectManny”(是否缺少using指令或程序集引用?) "

    -在两种情况下 选择多个 已使用(且似乎无法解决);在“收益回报c”行:

    " 当前上下文中不存在名称“c” "

    更新2

    对于我的简单场景(控件中没有容器/控件),这是可行的

    foreach (Control control in this.Controls)
    {
        var txtbx = control as TextBox;
        if (txtbx != null)
        {
            txtbx.TabStop = (!txtbx.ReadOnly);
        }
    }
    
    3 回复  |  直到 11 年前
        1
  •  3
  •   Richard Schneider    11 年前

    要简化示例,请执行以下操作:

    foreach (var control in Controls.OfType<TextBox>().Where(c => c.ReadOnly)
    {
        control.TabStop = false;
    }
    

    但是,您的示例不会处理所有控件,因为控件可以包含其他控件。你需要一个递归下降算法。

    IEnumerable<Control> Walk(Control control)
    {
       yield return control;
       foreach (var child in control.Controls.SelectMany(c=> Walk(c)))
       {
          yield return c;
       }
    }
    
    var q = Controls
      .SelectMany(c => Walk(c))
      .OfType<TextBox>().
      .Where(c => c.ReadOnly);
    foreach (var control in q)
    {
        control.TabStop = false;
    }
    
        2
  •  1
  •   SLaks    11 年前
    foreach (TextBox control in this.Controls.OfType<TextBox>())
    
        3
  •  0
  •   code4life    11 年前

    不是最有性能的,也不是最可读的代码,但以下是如何作为一行代码来实现的:

    this.Controls.OfType<TextBox>().ToList().ForEach(t => t.TabStop = !t.ReadOnly);

    …只是为了证明你可以。