XAML binding to CompositeCollection

不想你离开。 提交于 2020-02-15 06:41:12

问题


I have only one datagrid in a single view but the collections which are ItemsSource's of this datagrid are in different View Models. So is it possible to bind this single datagrid in view with the collections in two different View Models?

For each row in the grid, display an item from one collection, and an item from the other collection..! to display all columns in one row.

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(); 
    } 

} 

As per the above code, it displays like this Output..but, wanted to display all columns in one row.

So is it possible to bind this single datagrid in view with the collections in two different View Models?

Thanks for your help.


回答1:


And here is a working example of your code. I replaced the Itemsource of the Datagrid and made ViewModelTherapy and ViewModelPulse to Observable collections.

Code:

 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>

And here is a screenshot of the result




回答2:


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



来源:https://stackoverflow.com/questions/40124054/xaml-binding-to-compositecollection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!