none
Addressing Checkbox methods programatically RRS feed

  • Question

  • Hello.

    That's the name of the program with which I probably should have started my C# journey.  Instead, I've built a small application that identifies musical keys from individual notes through the application of falsification offsets from user identified notes.


    The program works, but I've got a dozen tickbox methods that all do exactly the same thing save for: 

    1.  A single numerical value which informs a downstream offset falsifier method,

    and


    2.  The name of the checkbox control, which is used to link the boolean value of the truthtable to the checkbox value, and provide forward and backwards functionality (i.e., it sets true on check, and false on uncheck).


    There has to be a better way to do this.  Ideally, I'd be able to parameterize the control name, and inherently bind the passed num value to the checkbox that triggered the event.  Even more ideally, I would be able to handle all of the tickboxes with a single method, with the linked values bound to the control state rather than repeating myself a dozen times.

    Or, just as likely, there is some solution that simply escapes my imagination.

    Your input is appreciated.

    //Is there a way to handle all of the checkboxes with a single entry? //Perhaps a way to bind a numerical value to each tickbox, //which would be passed to a handler method?

    private void CTick_CheckedChanged(object sender, EventArgs e) { byte num = 0; Roots[num] = CTick.Checked; //C is Checked, Roots[0] = True, else False KillMaj(); //Eliminate impossible keys DisplayKeys(); //Update display } //Same thing 11 more times private void CSharpTick_CheckedChanged(object sender, EventArgs e) { byte num = 1; Roots[num] = CSharpTick.Checked; KillMaj(); DisplayKeys(); } private void DTick_CheckedChanged(object sender, EventArgs e) { byte num = 2; Roots[num] = DTick.Checked; KillMaj(); DisplayKeys(); } [... you get the idea]



    A+, MCDST




    • Edited by Dr. Avery Sunday, July 28, 2019 9:21 PM
    Sunday, July 28, 2019 8:49 PM

Answers

  • Perhaps this would help where each CheckBox would have it's Tag property set in this case an int but could be anything to identify it.

    namespace WindowsFormsApp1
    {
        public partial class Form1 : Form
        {
    
            public Form1()
            {
                InitializeComponent();
                Shown += Form1_Shown;
            }
    
            private void Form1_Shown(object sender, EventArgs e)
            {
                Controls.OfType<CheckBox>()
                    .ToList()
                    .ForEach(cb =>
                    {
                        cb.CheckedChanged += CheckedChangedEvent;
                    });
            }
    
            private void CheckedChangedEvent(object sender, EventArgs e)
            {
                var checkBox = (CheckBox) sender;
                var currentIndexer = Convert.ToInt32((checkBox).Tag.ToString());
                Console.WriteLine(currentIndexer);
            }
        }
    }
    


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by Dr. Avery Monday, July 29, 2019 1:44 AM
    Sunday, July 28, 2019 9:28 PM
    Moderator

All replies

  • Perhaps this would help where each CheckBox would have it's Tag property set in this case an int but could be anything to identify it.

    namespace WindowsFormsApp1
    {
        public partial class Form1 : Form
        {
    
            public Form1()
            {
                InitializeComponent();
                Shown += Form1_Shown;
            }
    
            private void Form1_Shown(object sender, EventArgs e)
            {
                Controls.OfType<CheckBox>()
                    .ToList()
                    .ForEach(cb =>
                    {
                        cb.CheckedChanged += CheckedChangedEvent;
                    });
            }
    
            private void CheckedChangedEvent(object sender, EventArgs e)
            {
                var checkBox = (CheckBox) sender;
                var currentIndexer = Convert.ToInt32((checkBox).Tag.ToString());
                Console.WriteLine(currentIndexer);
            }
        }
    }
    


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by Dr. Avery Monday, July 29, 2019 1:44 AM
    Sunday, July 28, 2019 9:28 PM
    Moderator
  • Thanks for the reply!

    It'll probably take me about 3 days with the syntax reference to understand most of this, but this should help me get on the track of asking the right questions.

    [edit]

    @Kareninstructor

    Please let me know if I'm on the right track...

    It looks like you're saying checkbox.tag could be used to hold the numerical value I need to pass, which could then be converted to whatever datatype I require. 

    It also looks like "sender" is the direct reference I needed to address the triggering checkbox. 

    It'll probably take me a bit longer to figure out the Lambda operator.

    At any rate, I'll play around with it and see what I can figure out.

    • Edited by Dr. Avery Sunday, July 28, 2019 10:44 PM
    Sunday, July 28, 2019 9:53 PM
  • Yes you are on the right track.

    Sender is an object, we know it's a CheckBox so it's safe to cast it as a CheckBox. On a Button Click event sender is a Button etc.

    Since .Tag is of type object you can store anything sensible in the tag property, an int, a string, a bool etc, event a class instance. So if an int is not enough use a class e.g. a more complex example

    public class TagItem
    {
        public int Value1 { get; set; }
        public int Value2 { get; set; }
        public override string ToString()
        {
            return $"Value1 {Value1} Value2 {Value2}";
        }
    }

    Usage

    private void button1_Click(object sender, EventArgs e)
    {
        checkBox1.Tag = new TagItem() {Value1 = 12, Value2 = 34};
    }
    
    private void button2_Click(object sender, EventArgs e)
    {
        TagItem item = (TagItem) checkBox1.Tag;
        int value1 = item.Value1;
        Console.WriteLine(item);
    }


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Sunday, July 28, 2019 11:54 PM
    Moderator
  • I manually declared the tags to line up with my array, and once I got the console.writeline working, I was able to replace the 12 event handlers and have a significantly cleaner application. 

    Now I just have to figure out how it works.

    Thank you for your help.

    namespace Key_Finder
    {
        public partial class Form1 : Form
        {
            [...]
            public Form1()
            {
                InitializeComponent();
                Shown += TickWatch;
            }
    
            private void TickWatch(object sender, EventArgs e)
            {
                Controls.OfType<CheckBox>()
                    .ToList()
                    .ForEach(cb =>
                    {
                        cb.CheckedChanged += CheckedChangedEvent;
                    });
            }
    
            private void CheckedChangedEvent(object sender, EventArgs e)
            {
                var checkBox = (CheckBox)sender;
                var currentIndexer = Convert.ToByte((checkBox).Tag.ToString());
                DoTickEvent(currentIndexer);
            }
    
            private void DoTickEvent(byte NoteNum)
            {
                Roots[NoteNum] ^= true;
                KillMaj();
                DisplayKeys();
            }    
        }
    }


    • Edited by Dr. Avery Monday, July 29, 2019 2:13 AM
    Monday, July 29, 2019 2:10 AM