【问题标题】:WinUI 3 CommunityToolkit Datagrid displaying data from two models while using CommunityToolkit.MvvmWinUI 3 CommunityToolkit Datagrid 在使用 CommunityToolkit.Mvvm 时显示来自两个模型的数据
【发布时间】:2023-01-29 23:08:43
【问题描述】:

我的数据访问层中有两个模型:Table1 和 Table2。

我想使用 CommunityToolkit 中的 WinUI 3 DataGrid 来显示每个表中的两列:Table1.ColumnA、Table1.ColumnB、Table2.ColumnC、Table2.ColumnD

我的想法是在我的 ViewModel 类中使用 linq 来加入每个模型的可枚举:

IEnumerable<Table1> table1 = unitOfWorkDbGlobal.Table1.GetAll().ToList();
IEnumerable<Table2> table2 = unitOfWorkDbGlobal.Table2.GetAll().ToList();

                var JoinedTables = (from t1 in table1
                                join t2 in table2 on t1.TestGuid equals t2.TestGuid
                                select new
                                { t1.ColumnA, t1.ColumnB, 
                                t2.ColumnC, t2.ColumnD });

这种方法出现的问题是,我可以根据需要使用 table1 或 table2 创建 CommunityToolkit.Mvvm [ObservableProperty],但我无法使用 join 创建可观察属性,因为我使用的是 var 类型。当我使用 JoinedTables.GetType().Name 来确定显式类型时,它返回一个 Enumerable&lt;JoinIterator&gt;d__122 4 类型,这似乎是计算机官宣无法用作属性类型。

[ObservableProperty]
private ObservableCollection<Table1>? _table1Collection; //this works

[ObservableProperty]
private Enumerable<JoinIterator> d__122`4 _joinedTables; //Errors

如何将联接表制作成可以在 XAML 中绑定到 CommunityToolkit DataGrid 的 ObservableProperty。

这是我想使用的 XAML 示例(注意 ViewModel 在代码隐藏中分配为带有我上面添加的代码的类):

        <controls:DataGrid x:Name="MyDataGrid"
        AutoGenerateColumns="False"
        ItemsSource="{x:Bind ViewModel.JoinedTables, Mode=OneWay}">
            <controls:DataGrid.Columns>
                <controls:DataGridTextColumn 
                Header="Column A" 
                Width="250"
                Binding="{Binding ColumnA}" 
                FontSize="14" />
                <controls:DataGridTextColumn 
                Header="Column B" 
                Width="250"
                Binding="{Binding ColumnB}" 
                FontSize="14" />
                <controls:DataGridTextColumn 
                Header="Column C" 
                Width="250"
                Binding="{Binding ColumnC}" 
                FontSize="14" />
                <controls:DataGridTextColumn 
                Header="Column D" 
                Width="250"
                Binding="{Binding ColumnD}" 
                FontSize="14" />
            </controls:DataGrid.Columns>
        </controls:DataGrid>

【问题讨论】:

    标签: c# linq datagrid winui-3 community-toolkit-mvvm


    【解决方案1】:

    您需要为连接的表创建一个类型。像这样的东西。

    ViewModel.cs

    using CommunityToolkit.Mvvm.ComponentModel;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    
    namespace DataGridTests;
    
    public class Table1
    {
        public int Id { get; set; }
        public string ColumnA { get; set; } = string.Empty;
        public string ColumnB { get; set; } = string.Empty;
    }
    
    public class Table2
    {
        public int Id { get; set; }
        public string ColumnC { get; set; } = string.Empty;
        public string ColumnD { get; set; } = string.Empty;
    }
    
    public partial class JoinedTable : ObservableObject
    {
        [ObservableProperty]
        private string columnA = string.Empty;
    
        partial void OnColumnAChanged(string value)
        {
            // Update database.
        }
    
        public string ColumnB { get; set; } = string.Empty;
    
        public string ColumnC { get; set; } = string.Empty;
        public string ColumnD { get; set; } = string.Empty;
    }
    
    public partial class MainWindowViewModel : ObservableObject
    {
        [ObservableProperty]
        private ObservableCollection<JoinedTable> joinedTables = new();
    
        public MainWindowViewModel()
        {
            IEnumerable<JoinedTable> joinedTablesSource = Table1.Join(
                Table2,
                table1 => table1.Id,
                table2 => table2.Id,
                (table1, table2) => new JoinedTable()
                {
                    ColumnA = table1.ColumnA,
                    ColumnB = table1.ColumnB,
                    ColumnC = table2.ColumnC,
                    ColumnD = table2.ColumnD,
                });
    
            JoinedTables = new ObservableCollection<JoinedTable>(joinedTablesSource);
        }
    
        private ObservableCollection<Table1> Table1 { get; set; } = new()
        {
            {new Table1() { Id = 1, ColumnA="Table1-A-1", ColumnB="Table1-B-1" } },
            {new Table1() { Id = 2, ColumnA="Table1-A-2", ColumnB="Table1-B-2" } },
            {new Table1() { Id = 3, ColumnA="Table1-A-3", ColumnB="Table1-B-3" } },
        };
    
        private ObservableCollection<Table2> Table2 { get; set; } = new()
        {
            {new Table2() { Id = 1, ColumnC="Table2-C-1", ColumnD="Table2-D-1" } },
            {new Table2() { Id = 20, ColumnC="Table2-C-2", ColumnD="Table2-D-2" } },
            {new Table2() { Id = 3, ColumnC="Table2-C-3", ColumnD="Table2-D-3" } },
        };
    }
    

    .xaml

    <toolkit:DataGrid ItemsSource="{x:Bind ViewModel.JoinedTables, Mode=OneWay}">
        <toolkit:DataGrid.Columns>
            <toolkit:DataGridTextColumn
                Binding="{Binding ColumnA, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                Header="A"
                IsReadOnly="False" />
            <toolkit:DataGridTextColumn
                Binding="{Binding ColumnB}"
                Header="B" />
            <toolkit:DataGridTextColumn
                Binding="{Binding ColumnC}"
                Header="C" />
            <toolkit:DataGridTextColumn
                Binding="{Binding ColumnD}"
                Header="D" />
        </toolkit:DataGrid.Columns>
    </toolkit:DataGrid>
    

    【讨论】:

    • 基本上,制造一个仅用于加入其他模型的手动模型类,对吗?这是典型的方法还是有其他处理连接模型类的方法?如果绑定模式是双向的,这是否允许更新数据库?
    • 另外,我注意到您在 ViewModel.cs 中有它。连接模型的自定义模型类在业务层或什至数据访问层的单独文件夹中会更好吗?
    • AFAIK,您需要一个具有属性的类型才能在 DataGrid 中显示它们。这就是为什么你需要像这样的课程连接表.
    • 我用 TwoWay 绑定示例更新了我的答案。请参阅连接表中的 ColumnS。
    猜你喜欢
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 2018-04-09
    • 2020-07-17
    相关资源
    最近更新 更多