当SelectedItem发生更改时,如何获取绑定的WPF Datagrid的最后一行以通知View Model?

时间:2013-03-07 17:30:55

标签: wpf mvvm datagrid selecteditem

这是我的第一篇文章 - 如果我需要,我欢迎任何有关如何发布问题的建议。

我有一个WPF DataGrid,其ItemsSource绑定到名为OrderDetails(List Of OrderDetails)的属性,SelectedItem绑定到名为CurrentOrderDetail的属性。

在CurrentOrderDetail属性中,我调用一个执行计算的方法。执行计算的方法循环遍历OrderDetails属性,并将属于该列表的每个OrderDetail的两个成员相乘以产生总成本。该方法只是简单地更新文本框绑定到表单上的另一个属性。

这一切都很有效 - 直到我到达DataGrid的最后一行。基本上,用户从第一行开始,点击Invoiced字段并输入数量并按Enter键,选择下一行。 SelectedItem更改并因此更新CurrentOrderDetail - 调用计算。这有效!用户重复该过程,一切都计算好,直到DataGrid中的最后一条记录被击中。当用户按Enter键结束Invoiced单元格上的编辑时,从不调用calculate方法 - 因为SelectedItem没有更改,因此CurrentOrderDetail属性永远不会更新。

我喜欢标准,因为我最近搬到了WPF / Silverlight和MVVM,所以我没有回头。因此,我试图以同样的方式保持这个应用程序。

我想我需要强制某些东西来触发SelectedItem更改。我曾想过在视图中挂钩事件并简单地强制导航,但这对我来说似乎有点难看。必须有一个更好的解决方案。我花了两天时间在这里和其他论坛,并尝试了我自己的几个想法,没有一个工作。

我可以要求用户导航到另一行以触发属性通知,但我不愿意。

这里只是DataGrid的XAML:

<DataGrid Name="grdData" Grid.Row="3" Grid.ColumnSpan="2" AutoGenerateColumns="False" CanUserAddRows="False" Margin="5,5,5,5" ItemsSource="{Binding Path=OrderDetails, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  SelectedItem="{Binding Path=CurrentOrderDetail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" BorderThickness="3" >
    <DataGrid.Columns>   
        <DataGridTextColumn Binding="{Binding Path=Part}" Header="Wyandot Part #" IsReadOnly="True" />
        <DataGridTextColumn Binding="{Binding Path=SupplierPartNumber}" Header="Supplier Part #" IsReadOnly="True" />
        <DataGridTextColumn Binding="{Binding Path=UnitPrice, StringFormat=c}" Header="Price" IsReadOnly="True" />
        <DataGridTextColumn Binding="{Binding Path=Account}" Header="Account" IsReadOnly="True" />
        <DataGridTextColumn Binding="{Binding Path=UDF5, Mode=TwoWay}" Header="Invoiced" IsReadOnly="False" />
    </DataGrid.Columns>
</DataGrid>

我的View模型中的片段是相关的。

Private m_orderDetails As List(Of OrderDetail)
Public Property OrderDetails As List(Of OrderDetail)
    Get
        Return m_orderDetails
    End Get
    Set(value As List(Of OrderDetail))
        m_orderDetails = value
        InvokePropertyChanged("OrderDetails")
    End Set
End Property

Private m_currentOrderDetail As OrderDetail
Public Property CurrentOrderDetail As OrderDetail
    Get
        Return m_currentOrderDetail
    End Get
    Set(value As OrderDetail)
        m_currentOrderDetail = value
        InvokePropertyChanged("CurrentOrderDetail")
        Calculate()
    End Set
End Property

Public Sub Calculate()
    Dim total As Decimal = 0

    For Each detail As OrderDetail In OrderDetails
        total += detail.UnitPrice * detail.UDF5
    Next

    PoTotal = CStr("$" & total.ToString)
End Sub

1 个答案:

答案 0 :(得分:0)

听起来像你的计算是在错误的改变事件上发生的。我将拥有用户正在更新的OrderDetail value属性触发属性更改事件并使用它来更新我的总数。

订阅每个OrderDetail的每个属性更改事件需要更多的工作,但这才是您真正关心的事情。我可能会使用ObservableCollection<OrderDetail>,然后在Collectionchanged事件中连接必要的侦听器。