【问题标题】:Linq from multiple Foreach来自多个 Foreach 的 Linq
【发布时间】:2018-08-28 01:38:02
【问题描述】:

如何将以下多个foreach 转换为 LINQ?

    foreach (var resourceOne in resourceList)
    {
        string s = (string)resourceOne;
        foreach (Control c in gridBtn.Children)
        {
            if (c.GetType() == typeof(ToggleButton))
            {
                int TagPlusOne = Convert.ToInt32(c.Tag) + 1;
                string PaddedResult = TagPlusOne.ToString().PadLeft(3, '0');
                if (PaddedResult == s)
                {
                    ((ToggleButton)c).BorderBrush = Brushes.Red;
                    ((ToggleButton)c).BorderThickness = new Thickness(3, 3, 3, 3);
                }
            }
        }
    } 

【问题讨论】:

    标签: c# linq


    【解决方案1】:
    IEnumerable<ToggleButton> query =
      from c in gridBtn.Children
      where c.GetType() == typeof(ToggleButton)
      let tagPlusOne = Convert.ToInt32(c.Tag) + 1
      let paddedResult = tagPlusOne.ToString().PadLeft(3, '0')
      join s in resourceList.Cast<string>() on paddedResult equals s
      select c;
    
    
    foreach(ToggleButton button in query)
    {
      button.BorderBrush = Brushes.Red;
      button.BorderThickness = new Thickness(3, 3, 3, 3);
    }
    

    【讨论】:

    • 被赞为更符合问题的精神
    • 好吧,这实际上好多了
    • 关于以下错误的任何想法:找不到源类型“UIElement Collection”的查询模式的任何实现。找不到。 gridBtn 实际上它是我的 wpf 网格控件
    • 如果 gridBtn.Children 没有实现 IEnumerable,你可以调用 OfType
    【解决方案2】:

    你真的不能,但是你可以通过使用WhereOfType来简单地做到这一点:

    foreach (var in gridBtn.Children.OfType<ToggleButton>)
    {
        int TagPlusOne = Convert.ToInt32(c.Tag) + 1;
        string PaddedResult = TagPlusOne.ToString().PadLeft(3, '0');
        foreach (var resourceOne in resourceList.Where(x => x == PaddedResult))
        {
            c.BorderBrush = Brushes.Red;
            c.BorderThickness = new Thickness(3, 3, 3, 3);
        }
    }
    

    免责声明:完全未经测试。

    【讨论】:

      【解决方案3】:

      最后,您需要foreach 或类似名称来设置按钮的属性,因为 LINQ 用于查询您的数据(通常无副作用),而不是改变它们。但是,您可以使用 LINQ 来简化查找要编辑的按钮。例如您的代码可以归结为:

      var targetButtons = gridBtn
          .Children
          .OfType<ToggleButton>()
          .Where(tb => resourceList.OfType<string>().Contains($"{Convert.ToInt32(tb.Tag) + 1}:D3"));
      
      foreach(var btn in targetButtons)
      {
          btn.BorderBrush = Brushes.Red;
          btn.BorderThickness = new Thickness(3, 3, 3, 3);
      }
      

      可以进一步调整/优化/重构。请注意,我已将 PadLeft(3, '0') 替换为具有相同作用的 D3 标准数字格式字符串。

      【讨论】:

      • 不知何故 $"{Convert.ToInt32(tb.Tag) + 1}:D3") 不适用于我的 WPF 。由于 $ 无法识别。我使用我的原始代码 padleft 并且它可以工作。谢谢
      • @LohZhiCheng $"..." 是一个interpolated string,类似于string.Format。这是 C# 6 的特性。如果它不可用,那么您可能使用的是旧版本的 C#。
      【解决方案4】:

      你可以做这样的事情(虽然我无法测试它,因为我没有你的环境):

      gridBtn.Children.Where(c =>
              c.GetType() == typeof(ToggleButton) && resourceList.Any(resourceOne =>
                  (string) resourceOne ==
                  Convert.ToInt32(c.Tag) + 1.ToString().PadLeft(3, '0')))
          .ToList().ForEach(c =>
          {
              ((ToggleButton) c).BorderBrush = Brushes.Red;
              ((ToggleButton) c).BorderThickness = new Thickness(3, 3, 3, 3);
          });
      

      【讨论】:

        【解决方案5】:

        您可以使用此代码。我为按钮和 WinForm 测试了这样的代码。 我希望代码对您有所帮助。

        resourceList.Where(resourceOne =>
                {
                    string s = (string)resourceOne;
                    gridBtn.Children.OfType<ToggleButton>().Where(c =>
                    {
                        var TagPlusOne = Convert.ToInt32(c.Tag) + 1;
                        var PaddedResult = TagPlusOne.ToString().PadLeft(3, '0');
                        return PaddedResult == s;
                    }).ToList().ForEach(c =>
                    {
                        c.BorderBrush = Brushes.Red;
                        c.BorderThickness = new Thickness(3, 3, 3, 3);
                    });
                    return true;
                });
        

        我认为您也可以使用 Select 而不是 Foreach。

        esourceList.Where(resourceOne =>
                {
                    string s = (string)resourceOne;
                    var enumerable = ActiveForm.Controls.OfType<Button>().Where(control =>
                    {
                        var TagPlusOne = Convert.ToInt32(control.Tag) + 1;
                        var PaddedResult = TagPlusOne.ToString().PadLeft(3, '0');
                        return PaddedResult == s;
                    }).Select(control =>
                    {
                        control.BackColor = Color.Aqua;
                        control.Cursor = Cursors.WaitCursor;
                        return control;
                    });
                    return true;
                });
        

        【讨论】:

        • 谢谢我已经用简化的代码找到了上面的可行答案。再次感谢
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多