【问题标题】:WPF-MVVM, Master - Detail datagrid with calculated column. Rate * Quantity = TotalWPF-MVVM,主 - 具有计算列的详细数据网格。费率 * 数量 = 总计
【发布时间】:2016-01-24 19:04:40
【问题描述】:

我有绑定到视图模型的数据输入表单。我遵循 EF 代码优先方法,详细信息表由模型中的可观察集合表示,如下所示。

public partial class item
{ 
    public item()
    {
        orders = new ObservableCollection<order>();
    }
}

一切正常,但在少数情况下,我有一个主条目,其中包含网格形式的详细信息。这是将 SelectedItem.Orders 绑定到详细网格的 xaml 部分。

<UserControl x:Class="ABCD.Views.itemView"
    ....
    DataContext="{Binding itemMaster, Source={StaticResource Locator}}"
    Height="Auto" Width="Auto">
    <Grid> 
        <Grid.ColumnDefinitions.... />
        <Grid.RowDefinitions..../>
        <DataGrid AutoGenerateColumns="False" VerticalAlignment="Top" ItemsSource="{Binding items}" SelectedItem="{Binding SelectedItem}" Name="dgitems" HorizontalAlignment="Stretch" RowDetailsVisibilityMode="VisibleWhenSelected" >
             <DataGrid.Columns>
                        <DataGridTextColumn x:Name="ItemNameColumn" Binding="{Binding Path=ItemName}" Header="Item Name" Width="125" />
                        <DataGridTextColumn x:Name="ItemCodeColumn" Binding="{Binding Path=ItemCode}" Header="Item Code" Width="75" />
                        <DataGridTextColumn x:Name="StockColumn" Binding="{Binding Path=StockLevel}" Header="Stock" Width="60" />
             </DataGrid.Columns>
        </DataGrid>
        <Label Grid.Column="3" Grid.Row="0" Margin="3,3,3,3" Content="Item Code"      VerticalAlignment="Center" />
        <TextBox Grid.Column="4" Grid.Row="0" HorizontalAlignment="Left" Margin="3,3,3,3" Name="ctrlItemCode" Text="{Binding Path=SelectedItem.ItemCode, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Width="120" Height="Auto" VerticalContentAlignment="Center" />
        <Label Grid.Column="3" Grid.Row="2" Margin="3,3,3,3" Content="Product Name" VerticalAlignment="Center" />
        <TextBox Grid.Column="4" Grid.Row="2" HorizontalAlignment="Left" Margin="3,3,3,3" Name="ctrlProductName" Text="{Binding Path=SelectedItem.ItemName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Width="120" Height="Auto" VerticalContentAlignment="Center" />
        <DataGrid Grid.Column="2" Grid.Row="16" Grid.ColumnSpan="3"  Height="145" AutoGenerateColumns="False" VerticalAlignment="Top" ItemsSource="{Binding SelectedItem.Orders}"  Name="dgOrders" HorizontalAlignment="Stretch" >
             <DataGrid.Columns>
                  <DataGridTemplateColumn Width="120">
                       <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                 <ComboBox DisplayMemberPath="OrderNumber" SelectedValuePath="OrderId"  ItemsSource="{Binding Path=DataContext.Orders,   RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" SelectedValue="{Binding Path=OrderId}" />
                             </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                  </DataGridTemplateColumn>
                  <DataGridTextColumn x:Name="QtyColumn" Binding="{Binding Path=Quantity}" Header="Qty" Width="75" />
                  <DataGridTextColumn x:Name="PriceColumn" Binding="{Binding Path=Price}" Header="Price" Width="75" />
                  <DataGridTextColumn x:Name="TotalColumn" Binding="{Binding Path=Total}" Header="Total" Width="75" />
              </DataGrid.Columns>
        </DataGrid>
   </Grid>
 </UserControl>

在这种情况下,我想在用户在网格中输入价格和数量后立即计算总数。我知道如果我们在 viewmodel 中有相关的属性,它可以被处理。但就我而言,Orders 是项目模型中的一个集合。

提前致谢。

【问题讨论】:

    标签: c# wpf mvvm datagrid inline-editing


    【解决方案1】:

    好的, 在论坛中搜索和寻求支持后,我找到了适合我情况的解决方案。只是在这里发布它对某人有用。

    简要介绍对我有用的最终答案。 可以做的是用视图模型包装每个实体。 因此,在那里使用该集合的数据网格将它的 ittermssource 绑定到 OrderVM 的 observablecollection 而不是 Order(它是实体类型)。

    然后,您可以在我的视图模型中将实体的属性与属性包装起来,并在其中放置任何额外的业务逻辑,例如当其中一个因素发生变化时,计算字段上的计算和提升属性发生变化。

    根据这个建议,我的代码中的以下更改帮助我解决了问题; 如下所示的 OrderVM 集合;

     public class OrderVM : baseViewModel
    {
        public OrderVM()
        {   }
        private order _order;
        public order Order
        {
            get
            {
                return _order;
            }
            set
            {
                _order = value;
                NotifyPropertyChanged();
            }
        }
    public decimal Percentage
        {
            get
            {
                return (decimal)_order.Percentage; //Without passing the selectedOrder.Percentage like this, It doesn't work
            }
            set
            {
                _order.Percentage = value;
                NotifyPropertyChanged();
                calculate();
            }
        }
        public decimal Qty
        {
            get
            {
                return (decimal)_order.Qty;
            }
            set
            {
                _order.Qty = value;
                NotifyPropertyChanged();
                calculate();
            }
        }
        public decimal Total
        {
            get
            {
                return (decimal)_order.Total;
            }
            set
            {
                _order.Total = value;
                NotifyPropertyChanged();
            }
        }
        private void calculate()
        {
            _order.Total = _order.Price * _order.Qty;
            NotifyPropertyChanged("Total");
        }
     }
    

    itemVM(MainVM)现在具有以下三个重要属性, Orders = orderVM 的 ObservableCollection SelectedItem //选择要编辑的项目 SelectedOrder //选择编辑的顺序

    public class itemsVM : baseViewModel
    {
        private item _selectedItem;
        private ObservableCollection<OrderVM> _orders;
        public ObservableCollection<OrderVM> Orders
        {
            get
            {
                if (SelectedItem != null)
                {
                    _orders = new ObservableCollection<OrderVM>();
                    foreach (Order ord in SelectedItem.Orders)
                    {
                        _orders.Add(new OrderVM { Order = ord });
                    }
                    return _orders;
                }
                else
                    return null;
            }
            set { _orders = value; }
        }
    

    //SelectedItem 属性 公共项目 SelectedItem { 得到 { 返回_selectedItem; } 放 { _selectedItem = 价值; NotifyPropertyChanged(); NotifyPropertyChanged("CanModify"); NotifyPropertyChanged("订单"); } }

    private OrderVM _selectedorder;
        public OrderVM SelectedOrder
        {
            get
            {
                return _selectedorder;
            }
            set
            {
                _selectedorder = value;
                NotifyPropertyChanged();
            }
        }
    }
    

    我的 xaml 如下;

    <DataGrid Grid.Column="2" Grid.Row="16" Grid.ColumnSpan="3"  Height="145" AutoGenerateColumns="False" VerticalAlignment="Top" 
          ItemsSource="{Binding Orders}" SelectedItem="{Binding SelectedOrder}" Name="dgOrders" HorizontalAlignment="Stretch" >
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="QtyColumn" Binding="{Binding Path=Qty}" Header="Qty" Width="75" />
            <DataGridTextColumn x:Name="PriceColumn" Binding="{Binding Path=Price}" Header="Price" Width="75" />
            <DataGridTextColumn x:Name="TotalColumn" Binding="{Binding Path=Total}" Header="Price" Width="75" />
        </DataGrid.Columns>
    </DataGrid>
    

    总对话可以在Conversation at MSDN Forums找到

    【讨论】:

      猜你喜欢
      • 2011-02-11
      • 2011-10-05
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      • 1970-01-01
      • 2016-08-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多