Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle many checkboxes in MVVM (WPF)?

I have a list of extensions each with it's own checkbox that user needs to choose from: enter image description here

In the end I need to have a List or an ObservableCollection of all the extensions chosen.

Doing this non-MVVM is quite straight forward. I create the event of Checked or Unchecked, and I add the content of the sender.

View:

<CheckBox Checked="ToggleButton_OnChecked" Unchecked="ToggleButton_OnUnchecked">exe</CheckBox>

Code Behind:

    private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
    {
        var ext = ((CheckBox) sender).Content.ToString();
        Model.FirstRun.ExcludeExt.Add(ext);
    }

    private void ToggleButton_OnUnchecked(object sender, RoutedEventArgs e)
    {
        var ext = ((CheckBox)sender).Content.ToString();
        Model.FirstRun.ExcludeExt.Remove(ext);
    }

If I want to do this MVVM style, as far as I know - I have to create a property for each one of the checkboxes and bind them to the UI. This is a lot of work.

Is there any simpler way?

like image 736
Maverick Meerkat Avatar asked Jul 04 '17 08:07

Maverick Meerkat


Video Answer


1 Answers

You should think about a structure first and then it is not that much work and pretty straight forward to use.

For example: you have groups of extensions. I would create somethink like this (just pseudo code; e.g. no INotifyPropertyChanged implemented).

public class ExtensionGroup
{
    public string Name {get; set;}
    public ObservableCollection<ExtensionInfo> ExtensionInfos {get; set;}
}

public class ExtensionInfo
{
    public string Extension {get; set;}
    public bool IsChecked {get; set;}

    public ExtensionInfo(string extension)
    {
        Extension = extension;
    }
}

And in your ViewModel you can create

public ObservableCollection<ExtensionGroup> ExtensionGroups {get; set;}

Now you have to add the data like this

var extensionGroup = new ExtensionGroup{Name = "Executables"};
extensionGroup.ExtensionInfos.Add(new ExtensionInfo("exe");
extensionGroup.ExtensionInfos.Add(new ExtensionInfo("bat");

and after that you have a list with all groups including the extensions.

In you view you can bind this data and you're done. For the view you could use a ListView with a DataTemplate or some other items control.

Your view will get a lot easier with less code because you just have to specify the layout one time.

/edit This is a sample implementation of the xaml. I used a ItemsControl instead of a ListView.

<ItemsControl ItemsSource="{Binding ExtensionGroups}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Label Content="{Binding Name}"/>
                <ItemsControl ItemsSource="{Binding ExtensionInfos}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding IsChecked}"
                                      Content="{Binding Extension}"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Looks like this (just added two groups with two extensions). Example

like image 175
Mighty Badaboom Avatar answered Oct 03 '22 14:10

Mighty Badaboom