A WinForm application that filters users











up vote
0
down vote

favorite












I built a small WinForm application that has checkboxes to filters users with different properties.



Each user has a name, color and number.

With the program you can filter by color or name the users that you will see:
enter image description here



Inside the application there is a static list of users:



// SomeUser(<name>, <color>, <number>);
SomeUser("user1", "red", "one");
SomeUser("user2", "blue", "one");
SomeUser("user3", "red", "two");
SomeUser("user4", "blue", "two");
SomeUser("user4", "yellow", "two");
SomeUser("user4", "blue", "three");


The application works as expected.
If you are not specified any filters, it will show you all.

There is OR inside each groupbox.

There is AND bettwen the groupboxes.
Meaning:

If you checked red and blue, it will search for users that have red color OR blue color.

If you checked red, blue and one, it will search for users that have red OR blue color AND one number.

I hope you understand from these two small examples.



This is the filter function:



void countFinding(CheckBox checkbox, string userField, ref int found)
{
if (checkbox.Checked)
{
if (userField == checkbox.Text)
{
found++;
}
}
}

private bool isFilter(SomeUser user)
{
bool isAllowed = false;

int shouldBeFound = 0;
int found = 0;
if(this.checkBoxRed.Checked || this.checkBoxBlue.Checked)
{
shouldBeFound++;
countFinding(this.checkBoxRed, user.color, ref found);
countFinding(this.checkBoxBlue, user.color, ref found);
}

if (this.checkBoxOne.Checked || this.checkBoxTwo.Checked)
{
shouldBeFound++;
countFinding(this.checkBoxOne, user.number, ref found);
countFinding(this.checkBoxTwo, user.number, ref found);
}

if (shouldBeFound == found)
{
isAllowed = true;
}

return isAllowed;
}


Inside the isFilter() function I am checking twice the same checkbox.

In the first if I am checking:
if(this.checkBoxRed.Checked || this.checkBoxBlue.Checked)
and if one of them is true it goes (twice) to an inner function (countFinding())that also checks if the checkbox is checked.



So, it appear them I am checking at least one checkbox twice to see if it checked.



Is it possible to make it better? what do you think?










share|improve this question


























    up vote
    0
    down vote

    favorite












    I built a small WinForm application that has checkboxes to filters users with different properties.



    Each user has a name, color and number.

    With the program you can filter by color or name the users that you will see:
    enter image description here



    Inside the application there is a static list of users:



    // SomeUser(<name>, <color>, <number>);
    SomeUser("user1", "red", "one");
    SomeUser("user2", "blue", "one");
    SomeUser("user3", "red", "two");
    SomeUser("user4", "blue", "two");
    SomeUser("user4", "yellow", "two");
    SomeUser("user4", "blue", "three");


    The application works as expected.
    If you are not specified any filters, it will show you all.

    There is OR inside each groupbox.

    There is AND bettwen the groupboxes.
    Meaning:

    If you checked red and blue, it will search for users that have red color OR blue color.

    If you checked red, blue and one, it will search for users that have red OR blue color AND one number.

    I hope you understand from these two small examples.



    This is the filter function:



    void countFinding(CheckBox checkbox, string userField, ref int found)
    {
    if (checkbox.Checked)
    {
    if (userField == checkbox.Text)
    {
    found++;
    }
    }
    }

    private bool isFilter(SomeUser user)
    {
    bool isAllowed = false;

    int shouldBeFound = 0;
    int found = 0;
    if(this.checkBoxRed.Checked || this.checkBoxBlue.Checked)
    {
    shouldBeFound++;
    countFinding(this.checkBoxRed, user.color, ref found);
    countFinding(this.checkBoxBlue, user.color, ref found);
    }

    if (this.checkBoxOne.Checked || this.checkBoxTwo.Checked)
    {
    shouldBeFound++;
    countFinding(this.checkBoxOne, user.number, ref found);
    countFinding(this.checkBoxTwo, user.number, ref found);
    }

    if (shouldBeFound == found)
    {
    isAllowed = true;
    }

    return isAllowed;
    }


    Inside the isFilter() function I am checking twice the same checkbox.

    In the first if I am checking:
    if(this.checkBoxRed.Checked || this.checkBoxBlue.Checked)
    and if one of them is true it goes (twice) to an inner function (countFinding())that also checks if the checkbox is checked.



    So, it appear them I am checking at least one checkbox twice to see if it checked.



    Is it possible to make it better? what do you think?










    share|improve this question
























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I built a small WinForm application that has checkboxes to filters users with different properties.



      Each user has a name, color and number.

      With the program you can filter by color or name the users that you will see:
      enter image description here



      Inside the application there is a static list of users:



      // SomeUser(<name>, <color>, <number>);
      SomeUser("user1", "red", "one");
      SomeUser("user2", "blue", "one");
      SomeUser("user3", "red", "two");
      SomeUser("user4", "blue", "two");
      SomeUser("user4", "yellow", "two");
      SomeUser("user4", "blue", "three");


      The application works as expected.
      If you are not specified any filters, it will show you all.

      There is OR inside each groupbox.

      There is AND bettwen the groupboxes.
      Meaning:

      If you checked red and blue, it will search for users that have red color OR blue color.

      If you checked red, blue and one, it will search for users that have red OR blue color AND one number.

      I hope you understand from these two small examples.



      This is the filter function:



      void countFinding(CheckBox checkbox, string userField, ref int found)
      {
      if (checkbox.Checked)
      {
      if (userField == checkbox.Text)
      {
      found++;
      }
      }
      }

      private bool isFilter(SomeUser user)
      {
      bool isAllowed = false;

      int shouldBeFound = 0;
      int found = 0;
      if(this.checkBoxRed.Checked || this.checkBoxBlue.Checked)
      {
      shouldBeFound++;
      countFinding(this.checkBoxRed, user.color, ref found);
      countFinding(this.checkBoxBlue, user.color, ref found);
      }

      if (this.checkBoxOne.Checked || this.checkBoxTwo.Checked)
      {
      shouldBeFound++;
      countFinding(this.checkBoxOne, user.number, ref found);
      countFinding(this.checkBoxTwo, user.number, ref found);
      }

      if (shouldBeFound == found)
      {
      isAllowed = true;
      }

      return isAllowed;
      }


      Inside the isFilter() function I am checking twice the same checkbox.

      In the first if I am checking:
      if(this.checkBoxRed.Checked || this.checkBoxBlue.Checked)
      and if one of them is true it goes (twice) to an inner function (countFinding())that also checks if the checkbox is checked.



      So, it appear them I am checking at least one checkbox twice to see if it checked.



      Is it possible to make it better? what do you think?










      share|improve this question













      I built a small WinForm application that has checkboxes to filters users with different properties.



      Each user has a name, color and number.

      With the program you can filter by color or name the users that you will see:
      enter image description here



      Inside the application there is a static list of users:



      // SomeUser(<name>, <color>, <number>);
      SomeUser("user1", "red", "one");
      SomeUser("user2", "blue", "one");
      SomeUser("user3", "red", "two");
      SomeUser("user4", "blue", "two");
      SomeUser("user4", "yellow", "two");
      SomeUser("user4", "blue", "three");


      The application works as expected.
      If you are not specified any filters, it will show you all.

      There is OR inside each groupbox.

      There is AND bettwen the groupboxes.
      Meaning:

      If you checked red and blue, it will search for users that have red color OR blue color.

      If you checked red, blue and one, it will search for users that have red OR blue color AND one number.

      I hope you understand from these two small examples.



      This is the filter function:



      void countFinding(CheckBox checkbox, string userField, ref int found)
      {
      if (checkbox.Checked)
      {
      if (userField == checkbox.Text)
      {
      found++;
      }
      }
      }

      private bool isFilter(SomeUser user)
      {
      bool isAllowed = false;

      int shouldBeFound = 0;
      int found = 0;
      if(this.checkBoxRed.Checked || this.checkBoxBlue.Checked)
      {
      shouldBeFound++;
      countFinding(this.checkBoxRed, user.color, ref found);
      countFinding(this.checkBoxBlue, user.color, ref found);
      }

      if (this.checkBoxOne.Checked || this.checkBoxTwo.Checked)
      {
      shouldBeFound++;
      countFinding(this.checkBoxOne, user.number, ref found);
      countFinding(this.checkBoxTwo, user.number, ref found);
      }

      if (shouldBeFound == found)
      {
      isAllowed = true;
      }

      return isAllowed;
      }


      Inside the isFilter() function I am checking twice the same checkbox.

      In the first if I am checking:
      if(this.checkBoxRed.Checked || this.checkBoxBlue.Checked)
      and if one of them is true it goes (twice) to an inner function (countFinding())that also checks if the checkbox is checked.



      So, it appear them I am checking at least one checkbox twice to see if it checked.



      Is it possible to make it better? what do you think?







      c# winforms






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 2 days ago









      E235

      1184




      1184






















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          0
          down vote













          I don't think that checking the state of the box twice is an issue. However, I do think this could be written in a more general way that would be easier to add more boxes / fields to later. For example, sticking with the current class structure:



          bool FieldMatchesFilterGroup(string field, params CheckBox group) 
          {
          return group.All(box => !box.Checked)
          || group.Any(box => box.Checked && box.Text == field);
          }

          bool UserMatchesFilters(SomeUser user)
          {
          return FieldMatchesFilterGroup(user.color, checkBoxRed, checkBoxBlue)
          && FieldMatchesFilterGroup(user.number, checkBoxOne, checkBoxTwo);
          }


          This could be made considerably more general, but at the cost of also becoming more complex, so whether that's worth doing depends on how you plan to use this code. The FieldMatchesFilterGroup method above is using LINQ, but you could do the same thing with a foreach loop:



          bool FieldMatchesFilterGroup(string field, params CheckBox group)
          {
          bool any = false, found = false;
          foreach(var box in group)
          {
          if(box.Checked)
          {
          any = true;
          found |= (box.Text == field);
          }
          }
          return !any || found;
          }


          Also, just as a style thing, the typical C# naming convention is UpperCamelCase for methods.






          share|improve this answer






























            up vote
            0
            down vote













            Assuming you have a handler for the click event of the button(filter) to apply the filters. You can get all the checked boxes from each panel into separate collections. A LINQ query can then apply the filters against each user:



            private void filter_Click(object sender, EventArgs e)
            {
            var checkedNumbers = numbers.Controls.OfType<CheckBox>().Where(x => x.Checked == true);
            var checkedColors = colors.Controls.OfType<CheckBox>().Where(x => x.Checked == true);
            dataGridView1.DataSource = (from user in users
            where (checkedNumbers.Count() == 0 ? true : checkedNumbers.Any(x => x.Text == user.number))
            && (checkedColors.Count() == 0 ? true : checkedColors.Any(x => x.Text == user.color))
            select user).ToList();
            }


            For each filter set, if the count is 0 it returns true, or you could say unfiltered, otherwise it checks if the users complies with the filter(s). This follows the requirements you've stipulated.



            While the above will work for this specific case, having different properties that you want to filter by, could be problematic. Using the group clause it's fairly easy to get all the checked boxes grouped by the panel name. If the panel names are exactly like the property names in the SomeUser class and the checkboxes text's are exactly like the values for those properties, one can use some simple reflection to compare the values:



            private void filter_Click(object sender, EventArgs e)
            {
            var checkedBoxes = (from panel in Controls.OfType<Panel>()
            from CheckBox cb in panel.Controls.OfType<CheckBox>()
            where cb.Checked == true
            group cb by panel.Name);
            dataGridView1.DataSource = (from SomeUser user in users
            where checkedBoxes.Count() == 0 ? true : checkedBoxes.All
            (grp => grp.Any
            (cb => cb.Text == $"{user.GetType().GetProperty(grp.Key).GetValue(user)}"))
            select user).ToList();
            }





            share|improve this answer























              Your Answer





              StackExchange.ifUsing("editor", function () {
              return StackExchange.using("mathjaxEditing", function () {
              StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
              StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
              });
              });
              }, "mathjax-editing");

              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "196"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208570%2fa-winform-application-that-filters-users%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              0
              down vote













              I don't think that checking the state of the box twice is an issue. However, I do think this could be written in a more general way that would be easier to add more boxes / fields to later. For example, sticking with the current class structure:



              bool FieldMatchesFilterGroup(string field, params CheckBox group) 
              {
              return group.All(box => !box.Checked)
              || group.Any(box => box.Checked && box.Text == field);
              }

              bool UserMatchesFilters(SomeUser user)
              {
              return FieldMatchesFilterGroup(user.color, checkBoxRed, checkBoxBlue)
              && FieldMatchesFilterGroup(user.number, checkBoxOne, checkBoxTwo);
              }


              This could be made considerably more general, but at the cost of also becoming more complex, so whether that's worth doing depends on how you plan to use this code. The FieldMatchesFilterGroup method above is using LINQ, but you could do the same thing with a foreach loop:



              bool FieldMatchesFilterGroup(string field, params CheckBox group)
              {
              bool any = false, found = false;
              foreach(var box in group)
              {
              if(box.Checked)
              {
              any = true;
              found |= (box.Text == field);
              }
              }
              return !any || found;
              }


              Also, just as a style thing, the typical C# naming convention is UpperCamelCase for methods.






              share|improve this answer



























                up vote
                0
                down vote













                I don't think that checking the state of the box twice is an issue. However, I do think this could be written in a more general way that would be easier to add more boxes / fields to later. For example, sticking with the current class structure:



                bool FieldMatchesFilterGroup(string field, params CheckBox group) 
                {
                return group.All(box => !box.Checked)
                || group.Any(box => box.Checked && box.Text == field);
                }

                bool UserMatchesFilters(SomeUser user)
                {
                return FieldMatchesFilterGroup(user.color, checkBoxRed, checkBoxBlue)
                && FieldMatchesFilterGroup(user.number, checkBoxOne, checkBoxTwo);
                }


                This could be made considerably more general, but at the cost of also becoming more complex, so whether that's worth doing depends on how you plan to use this code. The FieldMatchesFilterGroup method above is using LINQ, but you could do the same thing with a foreach loop:



                bool FieldMatchesFilterGroup(string field, params CheckBox group)
                {
                bool any = false, found = false;
                foreach(var box in group)
                {
                if(box.Checked)
                {
                any = true;
                found |= (box.Text == field);
                }
                }
                return !any || found;
                }


                Also, just as a style thing, the typical C# naming convention is UpperCamelCase for methods.






                share|improve this answer

























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  I don't think that checking the state of the box twice is an issue. However, I do think this could be written in a more general way that would be easier to add more boxes / fields to later. For example, sticking with the current class structure:



                  bool FieldMatchesFilterGroup(string field, params CheckBox group) 
                  {
                  return group.All(box => !box.Checked)
                  || group.Any(box => box.Checked && box.Text == field);
                  }

                  bool UserMatchesFilters(SomeUser user)
                  {
                  return FieldMatchesFilterGroup(user.color, checkBoxRed, checkBoxBlue)
                  && FieldMatchesFilterGroup(user.number, checkBoxOne, checkBoxTwo);
                  }


                  This could be made considerably more general, but at the cost of also becoming more complex, so whether that's worth doing depends on how you plan to use this code. The FieldMatchesFilterGroup method above is using LINQ, but you could do the same thing with a foreach loop:



                  bool FieldMatchesFilterGroup(string field, params CheckBox group)
                  {
                  bool any = false, found = false;
                  foreach(var box in group)
                  {
                  if(box.Checked)
                  {
                  any = true;
                  found |= (box.Text == field);
                  }
                  }
                  return !any || found;
                  }


                  Also, just as a style thing, the typical C# naming convention is UpperCamelCase for methods.






                  share|improve this answer














                  I don't think that checking the state of the box twice is an issue. However, I do think this could be written in a more general way that would be easier to add more boxes / fields to later. For example, sticking with the current class structure:



                  bool FieldMatchesFilterGroup(string field, params CheckBox group) 
                  {
                  return group.All(box => !box.Checked)
                  || group.Any(box => box.Checked && box.Text == field);
                  }

                  bool UserMatchesFilters(SomeUser user)
                  {
                  return FieldMatchesFilterGroup(user.color, checkBoxRed, checkBoxBlue)
                  && FieldMatchesFilterGroup(user.number, checkBoxOne, checkBoxTwo);
                  }


                  This could be made considerably more general, but at the cost of also becoming more complex, so whether that's worth doing depends on how you plan to use this code. The FieldMatchesFilterGroup method above is using LINQ, but you could do the same thing with a foreach loop:



                  bool FieldMatchesFilterGroup(string field, params CheckBox group)
                  {
                  bool any = false, found = false;
                  foreach(var box in group)
                  {
                  if(box.Checked)
                  {
                  any = true;
                  found |= (box.Text == field);
                  }
                  }
                  return !any || found;
                  }


                  Also, just as a style thing, the typical C# naming convention is UpperCamelCase for methods.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 2 days ago

























                  answered 2 days ago









                  Errorsatz

                  5087




                  5087
























                      up vote
                      0
                      down vote













                      Assuming you have a handler for the click event of the button(filter) to apply the filters. You can get all the checked boxes from each panel into separate collections. A LINQ query can then apply the filters against each user:



                      private void filter_Click(object sender, EventArgs e)
                      {
                      var checkedNumbers = numbers.Controls.OfType<CheckBox>().Where(x => x.Checked == true);
                      var checkedColors = colors.Controls.OfType<CheckBox>().Where(x => x.Checked == true);
                      dataGridView1.DataSource = (from user in users
                      where (checkedNumbers.Count() == 0 ? true : checkedNumbers.Any(x => x.Text == user.number))
                      && (checkedColors.Count() == 0 ? true : checkedColors.Any(x => x.Text == user.color))
                      select user).ToList();
                      }


                      For each filter set, if the count is 0 it returns true, or you could say unfiltered, otherwise it checks if the users complies with the filter(s). This follows the requirements you've stipulated.



                      While the above will work for this specific case, having different properties that you want to filter by, could be problematic. Using the group clause it's fairly easy to get all the checked boxes grouped by the panel name. If the panel names are exactly like the property names in the SomeUser class and the checkboxes text's are exactly like the values for those properties, one can use some simple reflection to compare the values:



                      private void filter_Click(object sender, EventArgs e)
                      {
                      var checkedBoxes = (from panel in Controls.OfType<Panel>()
                      from CheckBox cb in panel.Controls.OfType<CheckBox>()
                      where cb.Checked == true
                      group cb by panel.Name);
                      dataGridView1.DataSource = (from SomeUser user in users
                      where checkedBoxes.Count() == 0 ? true : checkedBoxes.All
                      (grp => grp.Any
                      (cb => cb.Text == $"{user.GetType().GetProperty(grp.Key).GetValue(user)}"))
                      select user).ToList();
                      }





                      share|improve this answer



























                        up vote
                        0
                        down vote













                        Assuming you have a handler for the click event of the button(filter) to apply the filters. You can get all the checked boxes from each panel into separate collections. A LINQ query can then apply the filters against each user:



                        private void filter_Click(object sender, EventArgs e)
                        {
                        var checkedNumbers = numbers.Controls.OfType<CheckBox>().Where(x => x.Checked == true);
                        var checkedColors = colors.Controls.OfType<CheckBox>().Where(x => x.Checked == true);
                        dataGridView1.DataSource = (from user in users
                        where (checkedNumbers.Count() == 0 ? true : checkedNumbers.Any(x => x.Text == user.number))
                        && (checkedColors.Count() == 0 ? true : checkedColors.Any(x => x.Text == user.color))
                        select user).ToList();
                        }


                        For each filter set, if the count is 0 it returns true, or you could say unfiltered, otherwise it checks if the users complies with the filter(s). This follows the requirements you've stipulated.



                        While the above will work for this specific case, having different properties that you want to filter by, could be problematic. Using the group clause it's fairly easy to get all the checked boxes grouped by the panel name. If the panel names are exactly like the property names in the SomeUser class and the checkboxes text's are exactly like the values for those properties, one can use some simple reflection to compare the values:



                        private void filter_Click(object sender, EventArgs e)
                        {
                        var checkedBoxes = (from panel in Controls.OfType<Panel>()
                        from CheckBox cb in panel.Controls.OfType<CheckBox>()
                        where cb.Checked == true
                        group cb by panel.Name);
                        dataGridView1.DataSource = (from SomeUser user in users
                        where checkedBoxes.Count() == 0 ? true : checkedBoxes.All
                        (grp => grp.Any
                        (cb => cb.Text == $"{user.GetType().GetProperty(grp.Key).GetValue(user)}"))
                        select user).ToList();
                        }





                        share|improve this answer

























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          Assuming you have a handler for the click event of the button(filter) to apply the filters. You can get all the checked boxes from each panel into separate collections. A LINQ query can then apply the filters against each user:



                          private void filter_Click(object sender, EventArgs e)
                          {
                          var checkedNumbers = numbers.Controls.OfType<CheckBox>().Where(x => x.Checked == true);
                          var checkedColors = colors.Controls.OfType<CheckBox>().Where(x => x.Checked == true);
                          dataGridView1.DataSource = (from user in users
                          where (checkedNumbers.Count() == 0 ? true : checkedNumbers.Any(x => x.Text == user.number))
                          && (checkedColors.Count() == 0 ? true : checkedColors.Any(x => x.Text == user.color))
                          select user).ToList();
                          }


                          For each filter set, if the count is 0 it returns true, or you could say unfiltered, otherwise it checks if the users complies with the filter(s). This follows the requirements you've stipulated.



                          While the above will work for this specific case, having different properties that you want to filter by, could be problematic. Using the group clause it's fairly easy to get all the checked boxes grouped by the panel name. If the panel names are exactly like the property names in the SomeUser class and the checkboxes text's are exactly like the values for those properties, one can use some simple reflection to compare the values:



                          private void filter_Click(object sender, EventArgs e)
                          {
                          var checkedBoxes = (from panel in Controls.OfType<Panel>()
                          from CheckBox cb in panel.Controls.OfType<CheckBox>()
                          where cb.Checked == true
                          group cb by panel.Name);
                          dataGridView1.DataSource = (from SomeUser user in users
                          where checkedBoxes.Count() == 0 ? true : checkedBoxes.All
                          (grp => grp.Any
                          (cb => cb.Text == $"{user.GetType().GetProperty(grp.Key).GetValue(user)}"))
                          select user).ToList();
                          }





                          share|improve this answer














                          Assuming you have a handler for the click event of the button(filter) to apply the filters. You can get all the checked boxes from each panel into separate collections. A LINQ query can then apply the filters against each user:



                          private void filter_Click(object sender, EventArgs e)
                          {
                          var checkedNumbers = numbers.Controls.OfType<CheckBox>().Where(x => x.Checked == true);
                          var checkedColors = colors.Controls.OfType<CheckBox>().Where(x => x.Checked == true);
                          dataGridView1.DataSource = (from user in users
                          where (checkedNumbers.Count() == 0 ? true : checkedNumbers.Any(x => x.Text == user.number))
                          && (checkedColors.Count() == 0 ? true : checkedColors.Any(x => x.Text == user.color))
                          select user).ToList();
                          }


                          For each filter set, if the count is 0 it returns true, or you could say unfiltered, otherwise it checks if the users complies with the filter(s). This follows the requirements you've stipulated.



                          While the above will work for this specific case, having different properties that you want to filter by, could be problematic. Using the group clause it's fairly easy to get all the checked boxes grouped by the panel name. If the panel names are exactly like the property names in the SomeUser class and the checkboxes text's are exactly like the values for those properties, one can use some simple reflection to compare the values:



                          private void filter_Click(object sender, EventArgs e)
                          {
                          var checkedBoxes = (from panel in Controls.OfType<Panel>()
                          from CheckBox cb in panel.Controls.OfType<CheckBox>()
                          where cb.Checked == true
                          group cb by panel.Name);
                          dataGridView1.DataSource = (from SomeUser user in users
                          where checkedBoxes.Count() == 0 ? true : checkedBoxes.All
                          (grp => grp.Any
                          (cb => cb.Text == $"{user.GetType().GetProperty(grp.Key).GetValue(user)}"))
                          select user).ToList();
                          }






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited yesterday

























                          answered yesterday









                          tinstaafl

                          6,330727




                          6,330727






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Code Review Stack Exchange!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              Use MathJax to format equations. MathJax reference.


                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208570%2fa-winform-application-that-filters-users%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Mont Emei

                              Province de Neuquén

                              Journaliste