将模型的集合仅绑定到另一个集合的一部分

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

我需要 select/map 我的每个应用程序只有几个数据源,方法是首先选择左侧的应用程序,然后选择右侧的 mapped/selected(少数)数据源(请参阅屏幕截图)。

我经常遇到业务需求这样的场景,但是我无法想出一个好的解决方案来使用 WPF 绑定对此进行建模。

给定以下代码:

机型:

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>
                    <!-- how should I bind this checkbox? -->
                    <CheckBox DockPanel.Dock="Left" />
                    <TextBlock DockPanel.Dock="Left" Text="{Binding Name}" Margin="5,0,0,0" />
                </DockPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

GUI:

我可以使用什么模式来 "bind" 右边的复选框到右边的选择?

您应该使用 ICollectionView 过滤 ObservableCollection,这是此类情况下的标准方法。

特别是您将在左侧连接一个事件,该事件将更改 ICollectionView 并将绑定到右侧的列。

有关 ICollectionView 的更多信息,请点击此处:https://msdn.microsoft.com/en-us/library/system.componentmodel.icollectionview%28v=vs.110%29.aspx

您需要一个 DataSourceVM,它有一个 DataSource 和一个 IsSelected 属性。每个 SoftwareSolution 都有自己的 DataSourceVMs 集合,复选框绑定到 IsSelected

public SoftwareSolution(string name, IEnumerable<DataSource> dataSources)
{
    Name = name;
    this.DataSources = new ObservableCollection<DataSourceVM>(dataSource.Select(x => new DataSourceVM(x));
}