【问题标题】:WPF MVVM DataGrid populate with query at run timeWPF MVVM DataGrid 在运行时填充查询
【发布时间】:2021-03-10 17:28:59
【问题描述】:

作为 WPF 和 MVVM 的新手,过去几天我一直在努力解决这个问题。我已经在 stackoverflow 和 google/Youtube 上搜索了所有的帮助。

我有一个从模型的 BindableCollection (Caliburn Micro) 填充的 DataGrid(来自 OrderListView 的 biound)。但是,我需要从另一个 BindableCollection ProductList 中引入链接数据的属性(“程序”),(两个集合共享一个公共属性“代码”。

基本上,我希望 DataGrid 显示所有基于 OrderModel 的列,并在运行时使用 Products 集合中的相关数据填充名为 Programs 的列。

OrderModel.cs

public class OrderModel : BaseModel
    {
        private DateTime _orderDate;
        public DateTime OrderDate
        {
            get { return _orderDate; }
            set { _orderDate = value; OnPropertyChanged(); }
        }

        private string _code;
        public string Code
        {
            get { return _code; }
            set { _code = value; OnPropertyChanged(); }
        }

        private int _qty;
        public int Qty
        {
            get { return _qty; }
            set { _qty = value; OnPropertyChanged(); }
        }

ProductModel.cs

public class ProductModel : BaseModel
    {
        private string _code;
        public string Code
        {
            get { return _code; }
            set { _code = value; OnPropertyChanged(); }
        }

        private int _program;
        public int Program
        {
            get { return _program; }
            set { _program = value; OnPropertyChanged(); }
        }

DataGrid 在 OrderView.xaml

<DataGrid ItemsSource="{Binding OrderListView}" AutoGenerateColumns="False">
                <DataGrid.Columns>

                    <DataGridTemplateColumn>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Code}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>

                    <DataGridTemplateColumn>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Qty}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>

                    <DataGridTemplateColumn>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Program}"/>  <- This from ProductList ??
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>

                </DataGrid.Columns>
            </DataGrid>

OrderViewModel.cs

public class OrderViewModel : Screen
{
        private readonly IDataConnection _connect;

        private ICollectionView _orderView;
        public ICollectionView OrderListView
        {
            get => _orderView;
            set
            {
                _orderView = value;
                NotifyOfPropertyChange(() => OrderListView);
            }
        }

        private BindableCollection<OrderModel> _orderList;
        public BindableCollection<OrderModel> OrderList
        {
            get => _orderList;
            set
            {
                _orderList = value;
                NotifyOfPropertyChange(() => OrderList);
            }
        }

        private BindableCollection<ProductModel> _productList;
        public BindableCollection<ProductModel> ProductList
        {
            get { return _productList; }
            set { _productList = value; }
        }

        private string _code;
        public string Code
        {
            get { return _code; }
            set { _code = value; NotifyOfPropertyChange(() => Code); }
        }

        private int _qty;
        public int Qty
        {
            get { return _qty; }
            set { _qty = value; NotifyOfPropertyChange(() => Qty); }
        }

        private int _program;
        public int Program
        {
            get { return _program; }
            set
            {
                _program = value;

                NotifyOfPropertyChange(() => Program);
            }
        }

        public OrderViewModel(IDataConnection connect)
        {
            DisplayName = "Orders";

            var allOrders = await _connect.Orders_GetByDateRange(StartDate, EndDate);
            OrderList = new BindableCollection<OrderModel>(allOrders);
            OrderListView = CollectionViewSource.GetDefaultView(OrderList);

            var allProducts = await _connect.Products_GetAll();
            ProductList = new BindableCollection<ProductModel>(allProducts);
        }
}

基本上我想将关联程序拉入列中的模型中的“代码”匹配位置。

【问题讨论】:

    标签: wpf mvvm datagrid


    【解决方案1】:

    DataGrid 绑定到的ItemsSource 需要包含列绑定的所有属性。

    这意味着需要将Program 属性添加到您当前的OrderModel 或创建一个包含这两个属性的新模型。

    public class OrderModel : BaseModel
    {
        private DateTime _orderDate;
        public DateTime OrderDate
        {
            get { return _orderDate; }
            set { _orderDate = value; OnPropertyChanged(); }
        }
    
        private string _code;
        public string Code
        {
            get { return _code; }
            set { _code = value; OnPropertyChanged(); }
        }
    
        private int _qty;
        public int Qty
        {
            get { return _qty; }
            set { _qty = value; OnPropertyChanged(); }
        }
    
        private int _program;
        public int Program
        {
            get { return _program; }
            set { _program = value; OnPropertyChanged(); }
        }
    }
    

    然后需要将新的Program 值与其他集合中的值关联起来的逻辑。

    最干净的地方很可能是修改您的查询(假设您正在使用数据库连接)

    这很可能是在选择订单时包含JOIN

    但是,在客户端执行此操作,这意味着从 IDataConnection 接收到数据后将如下所示:

    using System.Linq;
    ...
    
    public OrderViewModel(IDataConnection connect)
    {
        DisplayName = "Orders";
    
        var allOrders = await _connect.Orders_GetByDateRange(StartDate, EndDate);
    
        var allProducts = await _connect.Products_GetAll();
        ProductList = new BindableCollection<ProductModel>(allProducts);
    
        foreach(var order in allOrders)
        {
            //assumes "Code" is unique within `ProductList`
            order.Program = ProductList.Single(p => p.Code == order.Code);
        }
        OrderList = new BindableCollection<OrderModel>(allOrders);
        OrderListView = CollectionViewSource.GetDefaultView(OrderList);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      相关资源
      最近更新 更多