gpt4 book ai didi

.net - 无法检测绑定(bind)到 EF 导航属性 MVVM 的 Datagrid 记录的更改(与 ListView 一起使用)

转载 作者:行者123 更新时间:2023-12-03 10:48:45 28 4
gpt4 key购买 nike

我有一个使用 MVVM 模型和 Entity Framework 5 进行数据访问的 WPF 应用程序。我有一个用户控件,其中包含员工的主/详细 View 。员工列表的 ListView 和“详细信息”网格,其数据上下文设置为 ListView 的选定员工。在该网格中,我有一个数据网格,它绑定(bind)到所选员工的导航属性(名为employee_certification 的属性)。所有绑定(bind)都正常工作并且没有错误,即使在输出窗口中也是如此。

问题 :我的问题是我无法检测到用户是否对导航属性的记录进行了任何更改。我目前使用更改跟踪器来测试实体中的更改以启用某些命令按钮,例如保存、撤消等。但是更改跟踪器从未检测到更改 内导航属性(称为employee_certification)。

以下是我从模型中获取员工实体的方法:

    Public Function GetEmployee_All(Context As FTC_Context) As ObservableCollection(Of employee) Implements IEmployeeDataService.GetEmployee_All
Dim employees = Context.employees.Include("employee_certification").ToList
Return New ObservableCollection(Of employee)(employees)
End Function

这是导航属性到数据网格的绑定(bind)。 (有效,这意味着它确实显示了正确的记录)
<DataGrid  Grid.Column="1" Grid.Row="2" MinWidth="350"        
ItemsSource="{Binding ElementName=DetailControl, Mode=TwoWay, Path=DataContext.employee_certification}"
CanUserAddRows="False" CanUserDeleteRows="False" >
<DataGrid.Columns>
</DataGrid.Columns>
</DataGrid>

即使绑定(bind)有效并且显示了正确的记录,我也无法确定用户是否对导航属性的记录进行了更改。

目标 :如果可能的话,我希望能够通过上下文本身检测到变化。我不想编写一个帮助类来将当前记录与数据库原件进行比较。有人可以帮我这样做吗?

编辑#1:
我认为这可能与数据网格有关。我的应用程序的另一个用户控件中有以下 ListView ,并且可以通过 EF 上下文跟踪对 ListView 记录中的记录字段所做的任何更改。

绑定(bind) vendor_account 是实体 vandor 的导航属性的 ListView :
 <ListView Grid.Column="1" Grid.Row="2"
Style="{DynamicResource FTC_SubListView}"
ItemContainerStyle="{DynamicResource FTC_SubListViewItem}"
ItemsSource="{Binding vendor_account, Mode=TwoWay}"
ItemTemplate="{DynamicResource FTC_VendorAccountsTemplate}" />

以下是我如何确定是否有更改以在我的 View 中启用保存按钮:
    Private Function CanSaveExecute() As Boolean
If _Selection.HasErrors = False Then
If (From entry In Context.ChangeTracker.Entries(Of vendor)() Where entry.Entity.idVendor = _Selection.idVendor And entry.State = EntityState.Modified Select entry).Count > 0 Then
Return True
ElseIf (From entry In Context.ChangeTracker.Entries(Of vendor_account)() Where entry.Entity.idVendor = _Selection.idVendor And (entry.State = EntityState.Modified Or entry.State = EntityState.Added) Select entry).Count > 0 Then
Return True
Else
Return False
End If
Else
Return False
End If
End Function

但如果我对数据网格使用以下内容,它永远不会对emplopyee_certification 导航属性进行更改计数:
    Private Function CanSaveExecute() As Boolean
If _Selection.HasErrors = False Then
If (From entry In Context.ChangeTracker.Entries(Of employee)() Where entry.Entity.idEmployee = _Selection.idEmployee And entry.State = EntityState.Modified Select entry).Count > 0 Then
Return True
ElseIf (From entry In Context.ChangeTracker.Entries(Of employee_certification)() Where entry.Entity.idEmployee = _Selection.idEmployee And entry.State = EntityState.Modified Select entry).Count > 0 Then
Return True
Else
Return False
End If
Else
Return False
End If
End Function

有谁知道为什么我的 ListView 允许更改跟踪器从更改跟踪器中查看 x 个已更改的实体,但不能使用数据网格?

编辑#2

好的,所以我缩小范围,我将 ListView 和数据网格放在同一个用户控件上,并以相同的方式将它们绑定(bind)到对象的数据上下文的导航属性,如上所述。员工具有作为链接记录的认证,这是员工对象的导航属性 (employee_certification)。

如果我对employee_certification 记录使用 ListView ,那么当我对这些记录进行更改时,我可以查询更改跟踪器以计算更改并在计数大于零时启用保存和撤消按钮。
 From entry In Context.ChangeTracker.Entries(Of employee_certification)() Where entry.Entity.idEmployee = _Selection.idEmployee And entry.State = EntityState.Modified Select entry).Count

当我使用数据网格并更改employee_certification 记录中的任何字段时,更改跟踪器不会将其中任何一个标记为已修改。

这是数据网格/ ListView 的定义方式
 <DataGrid  Grid.Column="1" Grid.Row="2" MinWidth="350"        
ItemsSource="{Binding employee_certification, Mode=TwoWay}"
CanUserAddRows="False" CanUserDeleteRows="False" >
<DataGrid.Columns>
<!-- Custom Defined Columns Go Here -->
</DataGrid.Columns>
</DataGrid>
<ListView Grid.Column="1" Grid.Row="3"
Style="{DynamicResource FTC_SubListView}"
ItemContainerStyle="{DynamicResource FTC_SubListViewItem}"
ItemsSource="{Binding employee_certification, Mode=TwoWay}"
ItemTemplate="{DynamicResource MyTemplate}">
</ListView>

由于内置排序等,我想使用数据网格。

编辑问题#2:为什么更改跟踪器跟踪 ListView 编辑中的更改而不是数据网格编辑?

最佳答案

这很令人沮丧。正如标题所暗示的,我认为问题出在 Entity Framework 、可观察集合和数据网格的一些交互上。事实证明,这只是 DataGridTemplateColumn 的绑定(bind)声明的问题。

根据这个SO ANSWER ,
使用您自己的 DataGridTemplateColumn 时,DataGrid 将所有绑定(bind)上的 UpdateSourceTrigger 更改为 Explicit。这必须由事件处理。但是,我正在使用 MVVM 模式并且不希望事件来处理单元格更改。我希望更改自动反射(reflect)到我的 View 模型中的集合中,所以我必须像这样显式声明列绑定(bind):(即对于组合框)

 SelectedValue="{Binding idCertification, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}"

我必须添加 UpdateSourceTrigger=LostFocus 才能将更改反射(reflect)回可观察的集合。现在我可以直接绑定(bind)到导航属性,并使用 Entity Framework 中的 Context.changeTracker 来计算更改(employee_certification,如上面的问题所示),以启用保存和撤消命令。

两天的搜索发现它只是对绑定(bind)的简单添加,arrrgh。

关于.net - 无法检测绑定(bind)到 EF 导航属性 MVVM 的 Datagrid 记录的更改(与 ListView 一起使用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15630168/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com