XAML绑定到CompositeCollection

时间:2016-10-19 06:44:18

标签: c# wpf xaml mvvm compositecollection

我在一个视图中只有一个数据网格,但是这个数据网格的ItemsSource的集合位于不同的视图模型中。那么可以将视图中的单个数据网格绑定到两个不同的视图模型中的集合吗?

对于网格中的每一行,显示一个集合中的项目和另一个集合中的项目..!显示一行中的所有列。

xaml:

DataContext="{DynamicResource ViewModelCombine}"> 

<Window.Resources> 
    <vm:ViewModelCombine x:Key="ViewModelCombine"/> 
</Window.Resources> 

<Grid> 
        <Grid.RowDefinitions> 
            <RowDefinition Height="Auto"/> 
        </Grid.RowDefinitions> 

     <DataGrid> 

            <DataGrid.Resources>
                <CollectionViewSource x:Key="ViewModelPulse" Source="{Binding VP}"/>
                <CollectionViewSource x:Key="ViewModeltherapy" Source="{Binding VT}"/>
            </DataGrid.Resources>

            <DataGrid.ItemsSource> 
                <CompositeCollection> 
                    <CollectionContainer Collection="{Binding Source={StaticResource ViewModelCombine}, Path=VP}" /> 
                    <CollectionContainer Collection="{Binding Source={StaticResource ViewModelCombine}, Path=VT}" /> 
                </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}" 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 MainWindow() 
{ 
    InitializeComponent(); 
    ViewModelCombine VMC = new ViewModelCombine(); 
    this.DataContext = VMC; 
} 

ViewModelCombine.cs

public class ViewModelCombine 
{ 
    public ViewModelTherapy VT { get; set; } 
    public ViewModelPulse VP { get; set; }

    public ViewModelCombine() 
    { 
        VT = new ViewModelTherapy(); 
        VP = new ViewModelPulse(); 
    } 

} 

根据上面的代码,它显示如下Output ..但是,想要在一行中显示所有列。

那么可以将视图中的单个数据网格绑定到两个不同的视图模型中的集合吗?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

这是一个代码的工作示例。我替换了Datagrid的Itemsource,并将ViewModelTherapy和ViewModelPulse转换为Observable集合。

代码:

 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 = 2 Name = "test2", Description = "desc" });
        this.DataContext = VMC;
    }

}

public class ViewModelCombine
{
    public ObservableCollection<ViewModelTherapy> VT { get; set; }
    public ObservableCollection<ViewModelPulse>  VP { get; set; }

    public ViewModelCombine()
    {
        VT = new ObservableCollection<ViewModelTherapy>();
        VP = new ObservableCollection<ViewModelPulse>();
    }

}

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 VT}"/>
    <CollectionViewSource x:Key="ViewSource2" Source="{Binding VP}"/>

    <CompositeCollection x:Key="CombinedCollection">
        <CollectionContainer Collection="{Binding Source={StaticResource ViewSource1}}" />
        <CollectionContainer Collection="{Binding Source={StaticResource ViewSource2}}" />
     </CompositeCollection>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <DataGrid ItemsSource="{StaticResource CombinedCollection}">


        <DataGrid.Columns>
            <DataGridTextColumn Header="AMP" Binding="{Binding ID}" Width="100"/>
            <DataGridTextColumn Header="PW" Binding="{Binding Name}" Width="100" />
            <DataGridTextColumn Header="DZ0" Binding="{Binding xaxa}" Width="100" />
            <DataGridTextColumn Header="DELTA" Binding="{Binding Description}" Width="100" />
        </DataGrid.Columns>

    </DataGrid>

</Grid>

以下是结果的屏幕截图

enter image description here

答案 1 :(得分:0)

Have you tried the following:

First set the Datagrid itemssource to ViewModelCombine. Then make the following changes in xaml (This example is only a demonstration cause i don't know which values are included in VT and VP but i think you could figure this out):

public MainWindow() 
{ 
    InitializeComponent(); 
    ViewModelCombine VMC = new ViewModelCombine(); 
    dgr.DataContext = VMC; 
} 

Xaml:

<Grid> 
        <Grid.RowDefinitions> 
            <RowDefinition Height="Auto"/> 
        </Grid.RowDefinitions> 

     <DataGrid x:Name="dgr"> 

           <DataGrid.Resources>
            <CollectionViewSource x:Key="ViewModelPulse" Source="{Binding VP}"/>
            <CollectionViewSource x:Key="ViewModeltherapy" Source="{Binding VT}"/>
        </DataGrid.Resources>

        <DataGrid.ItemsSource> 
            <CompositeCollection> 
                <CollectionContainer Collection="{Binding Source={StaticResource ViewModelCombine}, Path=VP}" /> 
                <CollectionContainer Collection="{Binding Source={StaticResource ViewModelCombine}, Path=VT}" /> 
            </CompositeCollection> 
        </DataGrid.ItemsSource> 


            <DataGrid.Columns> 
                <DataGridTextColumn Header="AMP" Binding="{Binding VT.AMP}" Width="100"/> 
                <DataGridTextColumn Header="PW" Binding="{Binding VP.PW}" Width="100" /> 
                <DataGridTextColumn Header="DZ0" Binding="{Binding VP.DZ0}" Width="100" /> 
                <DataGridTextColumn Header="DELTA" Binding="{Binding VP.DELTA}" Width="100" /> 
                <DataGridTextColumn Header="DZ1" Binding="{Binding VT.DZ1}"   Width="100"/> 
                <DataGridTextColumn Header="M" Binding="{Binding VP.M}" Width="100" /> 
                <DataGridTextColumn Header="DZ2" Binding="{Binding VP.DZ2}" Width="100" /> 
                <DataGridTextColumn Header="N" Binding="{Binding VP.N}" Width="100" /> 
            </DataGrid.Columns> 

    </DataGrid> 

</Grid> 

UPDATE:

In this link you will find a very good example for the composite collections in wpf. It includes a solution with Listview, Listbox and Gridview.

https://code.msdn.microsoft.com/windowsdesktop/Combining-item-sources-in-65408473

<Window.Resources>
        <!--Collection views for the ObservableCollections in the view model or code behind.-->
        <CollectionViewSource x:Key="BooksViewSource" Source="{Binding Books}"/>
        <CollectionViewSource x:Key="MoviesViewSource" Source="{Binding Movies}"/>
        <CollectionViewSource x:Key="AlbumsViewSource" Source="{Binding Albums}"/>

        <!--Combine the colection views into a single composite collection-->
        <CompositeCollection x:Key="CombinedCollection">            
            <CollectionContainer Collection="{Binding Source={StaticResource BooksViewSource}}" />
            <CollectionContainer Collection="{Binding Source={StaticResource MoviesViewSource}}" />
            <CollectionContainer Collection="{Binding Source={StaticResource AlbumsViewSource}}" />
        </CompositeCollection>             
    </Window.Resources>

And then they bind the collection to the controls. I would like to mention that in your code you are missing the Lists. The classes ViewModelPulse and ViewModeltherapy are not Lists of objects so your binding cannot work(as i cannot see their definitions in your question).

Hope that helps