使用CompositeCollection将两个ObservableCollection和Bind Datagrid合并为此MergedCollection作为源

时间:2016-10-20 06:52:28

标签: wpf xaml mvvm data-binding 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绑定到MergedCollection作为itemsource时发出问题...显示两行而不是一行的数据并检查输出here

要求是在一行中显示所有列......! 感谢。

1 个答案:

答案 0 :(得分:0)

确定。问题出在下面的代码中

 mergedSource.Add(collection1);
    mergedSource.Add(collection2);

此代码创建一个包含两个集合的唯一项目的列表,而不合并其属性。这就是为什么你的链接上有输出的原因。

而不是这样做我会建议以下解决方案

  1. 创建ObservableCollection<Newobject>
  2. 的集合
  3. Newobject应包含PulseTiming和TherapyTiming的所有属性
  4. 在同一个列表中添加了collection1和collection2中的项目,我会根据它们的ID合并(复制所有属性)collection1和collection2中的每个项目(如果你没有id属性,请添加它们)它将帮助您识别colelctions与Newobject之间的联系。

  5. 确保将数据网格绑定到新集合(itemsource)

  6. 该方法会在每个项目的一行中显示您的商品。但是,如果不将属性合并到新对象中,则无法做到这一点。

    更新:工作样本

    代码:

        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>
    

    截图:

    enter image description here