将模型的集合仅绑定到另一个集合的一部分
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));
}
我需要 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));
}