0

I am currently facing the following problem with a Menu Strip containing several different settings such as:

  • Show X
  • Show Y
  • Show Z

All those items have corresponding properties of the type bool, because those variables are also passed to other classes. Currently, when I click on "Show Y", I have a dedicated function called HandleShowY() which toggles the bool and the checkmark within the Menu Strip Item.

A new method for every newly added property seems like a huge code smell to me and requires a ton of added overhead for each new property. Thus, I came up with the idea to make a generic HandleMenuStripItemBool() which receives the property and the menu item by reference, such that only one method exists to handle this type of behaviour.

Unfortunately, I am running into problems while trying to pass my bool property to this method by reference, my knowledge of action, func and delegate has mostly faded away and only confuses me more and more after every new tutorial I read.

Example code:

// different properties of type bool, defined in form1
private bool ShowX { get; set; }
private bool ShowY { get; set; }

// generic menu strip item bool handler
private void HandleMenuStripItemBool(bool boolProp, ToolStripMenuItem menuItem)
{
    // toggle bool depending on current value
    // add check mark to or remove check mark from ToolStripMenuItem
}

// click event of the "Show X" menu strip item, defined in form1
private void showXToolStripMenuItem_Click(object sender, EventArgs e)
{
    HandleMenuStripItemBool(ShowX, showXToolStripMenuItem);
}

// click event of the "Show Y" menu strip item, defined in form1
private void showYToolStripMenuItem_Click(object sender, EventArgs e)
{
    HandleMenuStripItemBool(ShowY, showYToolStripMenuItem);
}

TL;DR: what is the best way to create a method which receives a property of the type bool by reference, in such a way that the method can be reused for several other properties?

Thanks in advance.

J. Doe
  • 101
  • 10
  • 1
    If would be great if you can show us some code. – hardkoded Mar 22 '18 at 11:34
  • You're right, I have added an example. – J. Doe Mar 22 '18 at 11:40
  • 1
    why do you need the bools if your menu item is checked? can't you just do `private bool ShowX { get { return showXToolStripMenuItem.Checked; } set { showXToolStripMenuItem.Checked = value; } }` ? – KMoussa Mar 22 '18 at 11:45
  • Wow, neat solution! This is working and while being slightly different from what I had in mind, a way better solution. Do you mind reposting your comment as an answer so I can mark it as a solution? – J. Doe Mar 22 '18 at 11:56
  • thanks, added an answer – KMoussa Mar 22 '18 at 12:04

3 Answers3

2

While not specifically answering how to pass the bool property by reference, why not just use the Checked value of the menu item, in which case you won't need to maintain the value of the bool property, and will only have a single source of truth

private bool ShowX 
{ 
     get { return showXToolStripMenuItem.Checked; } 
     set { showXToolStripMenuItem.Checked = value; } 
}
KMoussa
  • 1,568
  • 7
  • 11
0

You can pass it as reference and work on it inside the method:

        bool testBool;
        ToggleBoolValue(ref testBool);
        private void ToggleBoolValue(ref bool toggle)
        {
            toggle = !toggle;
            // some other tasks
        }
Michał Żołnieruk
  • 2,095
  • 12
  • 20
  • That's what I have tried before. Unfortunately, because my `ShowX` and `ShowY` variables are `properties`, I cannot pass them by reference. – J. Doe Mar 22 '18 at 11:51
  • https://stackoverflow.com/questions/1402803/passing-properties-by-reference-in-c-sharp @J.Doe – mjwills Mar 22 '18 at 11:58
0

If you're using a very modern version of C# (7.0 or later, I think), then you can make your properties be ref returning, and then use ref as Michal suggested:

using System;

public class Bob
{
  static void Main()
  {
    var b = new Bob();
    b.showYToolStripMenuItem_Click();
    Console.WriteLine(b.ShowY);
    Console.ReadLine();
  }
  // different properties of type bool, defined in form1
  private ref bool ShowX { get { return ref _showX; } }
  private ref bool ShowY { get { return ref _showY; }  }
  private bool _showX = false;
  private bool _showY = false;

  // generic menu strip item bool handler
  private void HandleMenuStripItemBool(ref bool boolProp)
  {
    boolProp = true;
  }

  // click event of the "Show X" menu strip item, defined in form1
  private void showXToolStripMenuItem_Click()
  {
    HandleMenuStripItemBool(ref ShowX);
  }

  // click event of the "Show Y" menu strip item, defined in form1
  private void showYToolStripMenuItem_Click()
  {
    HandleMenuStripItemBool(ref ShowY);
  }
}

(Main added and irrelevant parameters removed to make this a self-contained console demo)

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448