Linq添加order by到现有的selectMany

本文关键字:selectMany 添加 order by Linq | 更新日期: 2023-09-27 17:50:30

我有一个带分组框的表单。在这个组框中,我有另外3个组框。每个组框至少有1个按钮。

我在父组框中有一个按钮,它应该执行单击子组框中的所有按钮。

这部分我已经工作了,但现在的顺序是基于按钮的设计时放置顺序。

因为所有子分组框都在彼此下面,所以我想按位置排序。Y从第一个按钮开始。但我做不到。它一直从最后一个按钮开始。

这是我的LINQ正在工作:

var groups = parentBox.Controls.OfType<GroupBox>();
foreach (var button in
         groups.Select(groupBox => groupBox.Controls.OfType<Button>())
               .SelectMany(buttons =>
                     buttons.Where(button => button.Tag != null
                                             && button.Tag.ToString() == "run")))
{
    button.PerformClick();
}

我已经明白我需要添加。orderbydescent (button => button. location . y)在某处,但是我的尝试没有成功。

请建议。

Linq添加order by到现有的selectMany

可能比按钮的y位置更可靠和更灵活的一个选项是控件的TabIndex属性。你可以提前设定(设计),然后据此订购。您的用户还可以通过您定义的顺序中的按钮获得TAB的额外好处。

还要记住,有时将一个复杂的LINQ表达式分解成几个子表达式是有帮助的,即使只是为了调试目的。比如:

var groups = parentBox.Controls.OfType<GroupBox>();
var buttons = groups.SelectMany(groupBox => groupBox.Controls.OfType<Button>());
var buttonsWithRunTag = buttons.Where(button => button.Tag != null && button.Tag.ToString() == "run");
var orderByTabIndex = buttonsWithRunTag.OrderBy(button => button.TabIndex);
foreach (var button in orderByTabIndex)
{
   button.PerformClick();
}

您的困惑是由于控件位置总是相对于其直接父元素的顶部角。所以你必须按GroupBox的位置排序然后按Button的位置排序

var buttons = parent.Controls
                    .OfType<GroupBox>()
                    .OrderBy(x => x.Top)
                    .SelectMany(gb => gb.Controls.OfType<Button>()
                                       .OrderBy(x => x.Top))
                    .Where(button => button.Tag != null
                                  && button.Tag.ToString() == "run"))
                    .ToList();