Linq向现有的selectMany添加订单

时间:2014-03-14 20:59:32

标签: c# linq

我有一个带有groupbox的表单。在这个组框中,我有3个其他组框。每个groupbox至少有一个按钮。

我在父组框中有1个按钮,可以对子组框中的所有按钮执行单击操作。

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

因为所有子组合框都在彼此之下,所以我想按Location.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();
}

我已经明白我需要在某个地方添加 .OrderByDescending(button =&gt; button.Location.Y),但我的尝试没有用。

请告知。

2 个答案:

答案 0 :(得分:3)

可能比按钮的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();
}

答案 1 :(得分:1)

您的困惑是由于控制位置始终相对于直接父级的上角。因此,您必须按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();