Home > Net >  SelectedItem String for method
SelectedItem String for method

Time:01-22

i have a question. I select a Item from a dropdown. Now i like to use this selected item to change the values of a CheckedListbox. The data with the values for the CheckedListbox are in classes. For Example:

In the DropDown I can select Machine 1 and Machine 2. If I select Machine 1 the CheckedListbox show me Option 1, Option2 and Option 3. The Classes have different Names but the array with the options are in both Classes the same name.

I don't can't call the method with a string because a string is variable. How can i solve this? Thanks for your help.

Form1.cs

public Form1()
{
    InitializeComponent();
    cbox.Items.AddRange(new ListMachinetyp().machinetype);
}
private void cbox_SelectedIndexChanged(object sender, EventArgs e)
{
    string selectedItem = cbox.SelectedItem.ToString();
    clb1.Items.Clear();
    lbl.Text = selectedItem.ToString();
    clb1.Items.AddRange(new cbox.SelectedItem.ToString().options);
}

Machine1.cs

public class Machine1
{
    public string[] options = new string[] {
        "Option 1",
        "Option 2",
        "Option 3"
        };
}

Machine2.cs

public class Machine2
{
    public string[] options = new string[] {
        "Option 2",
        "Option 5"
        };
}

CodePudding user response:

public Form1()
{
    InitializeComponent();
    
    List<string> machineNames = new List<string>();
    machineNames.Add("Machine 1");
    machineNames.Add("Machine 2");
    cbox.DataSource = machineNames; // you can use any other list
}

void SetCheckedListboxSource(string selectedItem)
{
    if (selectedItem == "Machine 1") // you can also say if (selectedItem == machineNames[0])
       {
           Machine1 mach1 = new Machine1();
           checkedListBox.DataSource = null;
           checkedListBox.DataSource = mach1.options;
       }
    else if (selectedItem == "Machine 2") // you can also say if (selectedItem == machineNames[1])
       {
           Machine2 mach2 = new Machine2();
           checkedListBox.DataSource = null;
           checkedListBox.DataSource = mach2.options;
       }
}

private void cbox_SelectedIndexChanged(object sender, EventArgs e)
{
    string selectedItem = cbox.Text;
    
    SetCheckedListboxSource(selectedItem);
}

This is basic C# practice my friend. People on this site don't answer questions like this, I only answered because you seem to be new to this. Keep practicing, good luck ♥

CodePudding user response:

Your post does an excellent job of describing a behavior that you want your UI to have. If I'm following your code correctly, the desired outcome looks something like this:

screenshot

It is often the case that binding the UI controls to a class that models the intended behavior has many advantages to working with something like a ComboBox directly. Your code shows two controls:


ComboBox

The control you describe as the "DropDown" has the names of Machines to configure. A simple class to model this behavior would include the name of the machine, and the options it should include:

class OptionsConfig
{
    public string Device { get; set; } = string.Empty;
    public string[] Options { get; set; } = new string[0];
}

CheckedListBox

You state that the Options can be comprised of different classes. We will, however, make sure those other classes derive from a common base class with a name and IsChecked property.

class OptionClass
{
    public string Option { get; set; } = string.Empty;
    public bool IsChecked { get; set; }
}
class OptionClassA : OptionClass { }
class OptionClassB : OptionClass { }

For these two controls, we will now exercise some basic binding techniques.

Data Binding

In the method that loads the main form, initialize BindingList objects to use as data sources for the two controls.

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();

    protected override void onl oad(EventArgs e)
    {
        base.OnLoad(e);

        comboBox.DataSource = _optionConfigs;
        comboBox.DisplayMember = nameof(OptionsConfig.Device);

        // Add some machines and specify the config each should have
        _optionConfigs.Add(new OptionsConfig 
        {
            Device = "Machine 1",
            Options = new[] { "Option 1", "Option 2", "Option 3" },
        });
        _optionConfigs.Add(new OptionsConfig 
        { 
            Device = "Machine 2",
            Options = new[] { "Option 2", "Option 5", },
        });

        checkedListBox.DataSource = _filteredOptions;
        checkedListBox.DisplayMember = nameof(OptionClass.Option);
        // CheckedListBox does'not' support built-in binding for check states.
        // https://stackoverflow.com/a/39076505/5438626

        // Add some options from "different classes" to "All Options" collection.
        _allOptions.Add(new OptionClassA { Option = "Option 1" });
        _allOptions.Add(new OptionClassA { Option = "Option 2" });
        _allOptions.Add(new OptionClassA { Option = "Option 3" });

        _allOptions.Add(new OptionClassB { Option = "Option 4" });
        _allOptions.Add(new OptionClassB { Option = "Option 5" });

        onOptionsChooserChanged(this, EventArgs.Empty); // Init
        comboBox.SelectedIndexChanged  = onOptionsChooserChanged;
        checkedListBox.ItemCheck  = onItemCheckedChanged;
    }
    List<OptionClass> _allOptions = new List<OptionClass>();
    BindingList<OptionClass> _filteredOptions = new BindingList<OptionClass>();
    BindingList<OptionsConfig> _optionConfigs = new BindingList<OptionsConfig>();

Since the OptionsConfig class tightly associates Machine with the desired Options, it's now a simple matter of iterating the list of options, showing only those that are included in the current machine.

    private void onOptionsChooserChanged(object? sender, EventArgs e)
    {
        // Filter the options
        _filteredOptions.Clear();
        var config = (OptionsConfig) comboBox.SelectedItem;
        foreach (var option in config.Options)
        {
            var found = _allOptions.FirstOrDefault(_ => _.Option.Equals(option));
            if(found != null)
            {
                _filteredOptions.Add(found);
            }
        }
        ActiveControl = null;
    }

Respond to check changes

    private void onItemCheckedChanged(object? sender, ItemCheckEventArgs e)
    {
        var option = _filteredOptions[e.Index];
        option.IsChecked = !e.NewValue.Equals(CheckState.Unchecked);
    }
}
  • Related