Loh ZhiCheng
Loh ZhiCheng

Reputation: 25

Linq from multiple Foreach

How would I convert the following multiple foreach to 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);
                }
            }
        }
    } 

Upvotes: 0

Views: 304

Answers (5)

TheGeneral
TheGeneral

Reputation: 81473

You can't really, however you could simply it by using Where and OfType:

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);
    }
}

Disclaimer: totally untested.

Upvotes: 2

Vahid Asbaghi
Vahid Asbaghi

Reputation: 3

You could use this code. I tested a code like this for Buttons and WinForm. I hope the code helps you, in your case.

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;
        });

I think you could use Select instead of Foreach aswell.

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;
        });

Upvotes: 0

Saeb Amini
Saeb Amini

Reputation: 24380

In the end, you'll need a foreach or similar to set the properties on your buttons as LINQ is for querying your data (generally side-effect free), not mutating them. However, you can use LINQ to simplify finding the buttons you want to edit. e.g. your code could boil down to:

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);
}

Which can be further tweaked/optimized/refactored. Note I've replaced PadLeft(3, '0') with the D3 standard number format string which does the same thing.

Upvotes: 0

MetaColon
MetaColon

Reputation: 2923

You could do something like this (I couldn't test it though, as I don't have your environment):

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);
    });

Upvotes: 0

Amy B
Amy B

Reputation: 110071

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);
}

Upvotes: 2

Related Questions