【问题标题】:XAML binding to CompositeCollectionXAML 绑定到 CompositeCollection
【发布时间】:2017-02-28 15:51:23
【问题描述】:

我在单个视图中只有一个数据网格,但作为此数据网格的 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..但是,想在一行中显示所有列。

那么是否可以将视图中的这个单一数据网格与两个不同视图模型中的集合绑定?

感谢您的帮助。

【问题讨论】:

    标签: c# wpf xaml mvvm compositecollection


    【解决方案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>
    

    这是结果的截图

    【讨论】:

    • 考虑到 VP 有:FirstName,LastName & VT 有:ID,Salary 作为属性..应该在一行中显示所有属性(不像 VP 属性在一行中,VT 属性在另一行中,前提是以上)..谢谢。
    • 那么我想我或你的方法不可能实现你想要的。我建议创建一个新集合,将 VP 和 VT 基于它们的 ID 组合成一个新对象(如果可能,使用 linq)。并将该新集合绑定到数据网格。否则,使用 Composite 集合,您会将 2 个集合合二为一,但您不会组合它们的属性,我认为这是您想要做的。
    • 试图合并两个 ObservableCollection 并用这个 MergedCollection 绑定 Datagrid。请参考这个链接。 stackoverflow.com/q/40147381/7040506
    【解决方案2】:

    您是否尝试过以下方法:

    首先将 Datagrid itemssource 设置为 ViewModelCombine。然后在 xaml 中进行以下更改(此示例仅作为演示,因为我不知道 VT 和 VP 中包含哪些值,但我认为您可以弄清楚):

    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> 
    

    更新:

    在此链接中,您将找到 wpf 中复合集合的一个很好的示例。它包括一个带有 Listview、Listbox 和 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>
    

    然后他们将集合绑定到控件。我想提一下,在您的代码中,您缺少列表。 ViewModelPulse 和 ViewModeltherapy 类不是对象列表,因此您的绑定无法工作(因为我在您的问题中看不到它们的定义)。

    希望有帮助

    【讨论】:

    • 之前也尝试过,在这种情况下什么也不显示..!谢谢。
    • 您也可以尝试在 Binding="{Binding Path=VT.AMP}" 中设置路径。您是否在输出窗口中收到任何绑定错误?我已经在 xaml 中更新了答案。忘记添加资源和物品来源
    • 无显示/无数据,同时 Binding="{Binding VT.AMP}" 和 Binding="{Binding Path=VT.AMP}" 也没有绑定错误..谢谢..!
    • 嗯,我已经更新了我的答案,现在包含一个工作示例的链接。请随时检查
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    • 2013-05-26
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多