这是我的第一篇文章 - 我欢迎任何关于如何在需要时发布问题的建议。
我有一个 WPF DataGrid
,它ItemsSource
绑定到一个名为 OrderDetails(List Of OrderDetails) 的属性并SelectedItem
绑定到一个名为 CurrentOrderDetail 的属性。
在 CurrentOrderDetail 属性中,我调用了一个进行计算的方法。执行计算的方法循环通过 OrderDetails 属性并将属于该列表的每个 OrderDetail 的两个成员相乘以产生总成本。该方法只是简单地更新文本框绑定到表单上的另一个属性。
这一切都很好 - 直到我到达最后一行DataGrid
。基本上,用户从第一行开始,点击 Invoiced 字段并输入数量,然后按 Enter 键,选择下一行。更改并因此SelectedItem
更新 CurrentOrderDetail - 调用计算。这行得通!用户重复该过程,一切计算正常,直到DataGrid
命中最后一条记录。当用户按 Enter 键结束对 Invoiced 单元格的编辑时,从不调用计算方法 - 因为SelectedItem
未更改,因此从不更新 CurrentOrderDetail 属性。
我喜欢标准,因为我最近转向 WPF/Silverlight 和 MVVM,所以我没有回头。因此,我试图以同样的方式保持这个应用程序。
我想我需要强迫一些东西来触发SelectedItem
改变。我曾考虑过在视图中连接事件并简单地强制导航,但这对我来说似乎有点难看。一定有更好的解决方案。我已经在这里和其他论坛度过了两天,并尝试了我自己的几个想法,但都没有奏效。
我可以要求用户导航到另一行以触发属性通知,但我宁愿不这样做。
这只是 XAML 的DataGrid
:
<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>
以及我的视图模型中相关的片段。
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