使用 CompositeCollection 将两个 ObservableCollection 和 Bind Datagrid 与此 MergedCollection 合并为源
Merging two ObservableCollection and Bind Datagrid with this MergedCollection as source using CompositeCollection
.Xaml
DataContext="{DynamicResource ViewModelCombine}">
<Window.Resources>
<vm:ViewModelCombine x:Key="ViewModelCombine"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGrid x:Name="grd">
<DataGrid.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource ViewModelCombine}, Path=MergedSource}"/>
</CompositeCollection>
</DataGrid.ItemsSource>
<DataGrid.Columns>
<DataGridTextColumn Header="AMP" Binding="{Binding AMP}" Width="100"/>
<DataGridTextColumn Header="PW" Binding="{Binding PW}" Width="100" />
<DataGridTextColumn Header="DZ0" Binding="{Binding DZ0}" Width="100" />
<DataGridTextColumn Header="DELTA" Binding="{Binding DELTA}" Width="100" />
<DataGridTextColumn Header="DZ1" Binding="{Binding DZ1}" Width="100"/>
<DataGridTextColumn Header="M" Binding="{Binding M_View}" Width="100" />
<DataGridTextColumn Header="DZ2" Binding="{Binding DZ2}" Width="100" />
<DataGridTextColumn Header="N" Binding="{Binding N}" Width="100" />
</DataGrid.Columns>
</DataGrid>
</Grid>
.Xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ViewModelCombine VMC = new ViewModelCombine();
grd.DataContext = VMC;
}
}
ViewModelCombine.cs
public class ViewModelCombine
{
private ObservableCollection<TherapyTiming> secondsource;
public ObservableCollection<TherapyTiming> SecondSource
{
get { return secondsource; }
set { secondsource = value; }
}
private ObservableCollection<PulseTiming> firstsource;
public ObservableCollection<PulseTiming> FirstSource
{
get { return firstsource; }
set { firstsource = value; }
}
private CompositeCollection mergedSource;
public CompositeCollection MergedSource
{
get { return mergedSource; }
set { mergedSource = value; OnPropertyChanged("MergedSource"); }
}
public ViewModelCombine()
{
var secondinfo = new ViewModelTherapy();
SecondSource = secondinfo;
var firstinfo = new ViewModelPulse();
FirstSource = firstinfo;
mergedSource = new CompositeCollection();
CollectionContainer collection1 = new CollectionContainer() { Collection = SecondSource };
CollectionContainer collection2 = new CollectionContainer() { Collection = FirstSource };
mergedSource.Add(collection1);
mergedSource.Add(collection2);
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
使用 CompositeCollection 将 Datagrid 作为 itemsource 绑定到 MergedCollection 时出现问题..在两行而不是一行中显示数据并检查输出 here。
要求是在一行中显示所有列...!
谢谢
好的。问题出在下面的代码中
mergedSource.Add(collection1);
mergedSource.Add(collection2);
此代码创建一个列表,其中包含两个集合的唯一项目,而不合并它们的属性。这就是为什么您的 link.
上有输出的原因
与其这样做,我建议采用以下解决方案
- 创建一个集合
ObservableCollection<Newobject>
- 新对象应包含 PulseTiming 和 TherapyTiming 的所有属性
为了将 collection1 和 collection2 中的项目添加到同一个列表中,我将根据它们的 ID 合并(复制所有属性)collection1 和 collection2 中的每个项目(如果你不这样做,请添加它们具有 id 属性,因为它将帮助您识别集合之间的连接)到新对象。
确保将数据网格绑定到新集合 (itemsource)
该方法会将您的项目显示在一行中。但是如果不将属性合并到一个新对象中,您就无法做到这一点。
更新:工作示例
代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ViewModelCombine VMC = new ViewModelCombine();
VMC.VP.Add(new ViewModelPulse() { ID = 1, Name = "test1", xaxa = "xaxa" });
VMC.VT.Add(new ViewModelTherapy() { ID = 1, Name = "test1", Description = "desc" });
VMC.VP.Add(new ViewModelPulse() { ID = 2, Name = "test2", xaxa = "xaxa2" });
VMC.VT.Add(new ViewModelTherapy() { ID =2, Name = "test2", Description = "desc2" });
VMC.BuildSource();
this.DataContext = VMC;
}
}
public class ViewModelCombine
{
public ObservableCollection<ViewCommon> Source { get; set; }
public void BuildSource()
{
Source.Clear();
foreach(var itm in VT)
{
var itmF = VP.FirstOrDefault(x => x.ID == itm.ID);
if(itmF != null)
{
Source.Add(new ViewCommon() {
ID = itm.ID,
Description = itm.Description,
Name = itm.Name,
xaxa = itmF.xaxa
});
}
}
}
public ObservableCollection<ViewModelTherapy> VT { get; set; }
public ObservableCollection<ViewModelPulse> VP { get; set; }
public ViewModelCombine()
{
Source = new ObservableCollection<ViewCommon>();
VT = new ObservableCollection<ViewModelTherapy>();
VP = new ObservableCollection<ViewModelPulse>();
}
}
public class ViewCommon
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string xaxa { get; set; }
}
public class ViewModelTherapy
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class ViewModelPulse
{
public int ID { get; set; }
public string Name { get; set; }
public string xaxa { get; set; }
}
Xaml:
<Window.Resources>
<CollectionViewSource x:Key="ViewSource1" Source="{Binding Source}"/>
<CompositeCollection x:Key="CombinedCollection">
<CollectionContainer Collection="{Binding Source={StaticResource ViewSource1}}" />
</CompositeCollection>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGrid ItemsSource="{StaticResource CombinedCollection}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding ID}" Width="100"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="100" />
<DataGridTextColumn Header="xaxa" Binding="{Binding xaxa}" Width="100" />
<DataGridTextColumn Header="Description" Binding="{Binding Description}" Width="100" />
</DataGrid.Columns>
</DataGrid>
</Grid>
截图:
.Xaml
DataContext="{DynamicResource ViewModelCombine}">
<Window.Resources>
<vm:ViewModelCombine x:Key="ViewModelCombine"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGrid x:Name="grd">
<DataGrid.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource ViewModelCombine}, Path=MergedSource}"/>
</CompositeCollection>
</DataGrid.ItemsSource>
<DataGrid.Columns>
<DataGridTextColumn Header="AMP" Binding="{Binding AMP}" Width="100"/>
<DataGridTextColumn Header="PW" Binding="{Binding PW}" Width="100" />
<DataGridTextColumn Header="DZ0" Binding="{Binding DZ0}" Width="100" />
<DataGridTextColumn Header="DELTA" Binding="{Binding DELTA}" Width="100" />
<DataGridTextColumn Header="DZ1" Binding="{Binding DZ1}" Width="100"/>
<DataGridTextColumn Header="M" Binding="{Binding M_View}" Width="100" />
<DataGridTextColumn Header="DZ2" Binding="{Binding DZ2}" Width="100" />
<DataGridTextColumn Header="N" Binding="{Binding N}" Width="100" />
</DataGrid.Columns>
</DataGrid>
</Grid>
.Xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ViewModelCombine VMC = new ViewModelCombine();
grd.DataContext = VMC;
}
}
ViewModelCombine.cs
public class ViewModelCombine
{
private ObservableCollection<TherapyTiming> secondsource;
public ObservableCollection<TherapyTiming> SecondSource
{
get { return secondsource; }
set { secondsource = value; }
}
private ObservableCollection<PulseTiming> firstsource;
public ObservableCollection<PulseTiming> FirstSource
{
get { return firstsource; }
set { firstsource = value; }
}
private CompositeCollection mergedSource;
public CompositeCollection MergedSource
{
get { return mergedSource; }
set { mergedSource = value; OnPropertyChanged("MergedSource"); }
}
public ViewModelCombine()
{
var secondinfo = new ViewModelTherapy();
SecondSource = secondinfo;
var firstinfo = new ViewModelPulse();
FirstSource = firstinfo;
mergedSource = new CompositeCollection();
CollectionContainer collection1 = new CollectionContainer() { Collection = SecondSource };
CollectionContainer collection2 = new CollectionContainer() { Collection = FirstSource };
mergedSource.Add(collection1);
mergedSource.Add(collection2);
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
使用 CompositeCollection 将 Datagrid 作为 itemsource 绑定到 MergedCollection 时出现问题..在两行而不是一行中显示数据并检查输出 here。
要求是在一行中显示所有列...! 谢谢
好的。问题出在下面的代码中
mergedSource.Add(collection1);
mergedSource.Add(collection2);
此代码创建一个列表,其中包含两个集合的唯一项目,而不合并它们的属性。这就是为什么您的 link.
上有输出的原因与其这样做,我建议采用以下解决方案
- 创建一个集合
ObservableCollection<Newobject>
- 新对象应包含 PulseTiming 和 TherapyTiming 的所有属性
为了将 collection1 和 collection2 中的项目添加到同一个列表中,我将根据它们的 ID 合并(复制所有属性)collection1 和 collection2 中的每个项目(如果你不这样做,请添加它们具有 id 属性,因为它将帮助您识别集合之间的连接)到新对象。
确保将数据网格绑定到新集合 (itemsource)
该方法会将您的项目显示在一行中。但是如果不将属性合并到一个新对象中,您就无法做到这一点。
更新:工作示例
代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ViewModelCombine VMC = new ViewModelCombine();
VMC.VP.Add(new ViewModelPulse() { ID = 1, Name = "test1", xaxa = "xaxa" });
VMC.VT.Add(new ViewModelTherapy() { ID = 1, Name = "test1", Description = "desc" });
VMC.VP.Add(new ViewModelPulse() { ID = 2, Name = "test2", xaxa = "xaxa2" });
VMC.VT.Add(new ViewModelTherapy() { ID =2, Name = "test2", Description = "desc2" });
VMC.BuildSource();
this.DataContext = VMC;
}
}
public class ViewModelCombine
{
public ObservableCollection<ViewCommon> Source { get; set; }
public void BuildSource()
{
Source.Clear();
foreach(var itm in VT)
{
var itmF = VP.FirstOrDefault(x => x.ID == itm.ID);
if(itmF != null)
{
Source.Add(new ViewCommon() {
ID = itm.ID,
Description = itm.Description,
Name = itm.Name,
xaxa = itmF.xaxa
});
}
}
}
public ObservableCollection<ViewModelTherapy> VT { get; set; }
public ObservableCollection<ViewModelPulse> VP { get; set; }
public ViewModelCombine()
{
Source = new ObservableCollection<ViewCommon>();
VT = new ObservableCollection<ViewModelTherapy>();
VP = new ObservableCollection<ViewModelPulse>();
}
}
public class ViewCommon
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string xaxa { get; set; }
}
public class ViewModelTherapy
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class ViewModelPulse
{
public int ID { get; set; }
public string Name { get; set; }
public string xaxa { get; set; }
}
Xaml:
<Window.Resources>
<CollectionViewSource x:Key="ViewSource1" Source="{Binding Source}"/>
<CompositeCollection x:Key="CombinedCollection">
<CollectionContainer Collection="{Binding Source={StaticResource ViewSource1}}" />
</CompositeCollection>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGrid ItemsSource="{StaticResource CombinedCollection}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding ID}" Width="100"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="100" />
<DataGridTextColumn Header="xaxa" Binding="{Binding xaxa}" Width="100" />
<DataGridTextColumn Header="Description" Binding="{Binding Description}" Width="100" />
</DataGrid.Columns>
</DataGrid>
</Grid>
截图: