lundi 11 mai 2015

Bind a collection of a model to only a part of another collection

I have the requirement to select/map only a few of datasources for each of my applications, by first selecting the application on the left then the mapped/selected (few) datasources on the right (see screenshot).

I often have such a scenario as a business requirement, however I wasn't able to come up with a good solution to model this using WPF bindings.

Given the following code:

The models:

class DataSource
{
    public DataSource(string name)
    {
        Name = name;
    }

    public string Name { get; private set; }
}

class SoftwareSolution
{
    public SoftwareSolution(string name)
    {
        Name = name;
        this.DataSources = new ObservableCollection<DataSource>();
    }

    public string Name { get; private set; }
    public ObservableCollection<DataSource> DataSources { get; private set; }
}

class MainWindowViewModel
{
    public MainWindowViewModel()
    {
        this.SoftwareSolutions = new ObservableCollection<SoftwareSolution>();
        this.SoftwareSolutions.Add(new SoftwareSolution("Software 1"));
        this.SoftwareSolutions.Add(new SoftwareSolution("Software 2"));
        this.SoftwareSolutions.Add(new SoftwareSolution("Software 3"));

        this.AllAvailableDatasources = new ObservableCollection<DataSource>();
        this.AllAvailableDatasources.Add(new DataSource("SQL Server"));
        this.AllAvailableDatasources.Add(new DataSource("Oracle"));
        this.AllAvailableDatasources.Add(new DataSource("DB2"));
        this.AllAvailableDatasources.Add(new DataSource("MySQL"));
    }

    public ObservableCollection<DataSource> AllAvailableDatasources { get; private set; }
    public ObservableCollection<SoftwareSolution> SoftwareSolutions { get; private set; } 
}

XAML:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>

    <TextBlock Text="Application" />
    <ListBox Margin="0,25,5,0" VerticalAlignment="Stretch" ItemsSource="{Binding SoftwareSolutions}" DisplayMemberPath="Name" />

    <TextBlock Grid.Column="1" Text="DataSources" />
    <ListBox Grid.Column="1" Margin="0,25,0,0" VerticalAlignment="Stretch" ItemsSource="{Binding AllAvailableDatasources}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <DockPanel>
                    <CheckBox DockPanel.Dock="Left" />
                    <TextBlock DockPanel.Dock="Left" Text="{Binding Name}" Margin="5,0,0,0" />
                </DockPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

The GUI:

example gui

What pattern can I use to "bind" the checkboxes on the right to the selection on the right?

Aucun commentaire:

Enregistrer un commentaire