我创建了一个非常简单的新项目,只是为了测试微软WPF数据网格的行为。没有其他涉及,我只使用标准的DataGrid:
员工类实现IDataErrorInfo接口:
到目前为止,一切都很好。然后,在添加新行后尝试更新薪资值时会发生以下情况:
1. 为什么会这样?我使用DataGrid的方式有问题吗? 2. 是否有解决方法?
[编辑] ... 和解决方法
我终于找到了一个看起来像是解决方法的东西,即使我仍然不知道我现在认为是Microsoft DataGrid中的错误的原因。
如果在数据网格列中指定了绑定模式,并且带有验证,则会出现此错误;如果我不指定绑定模式,则一切正常。
我并不是很理解的是,据我所知默认的绑定模式是双向的...好吧,至少我解决了我的问题。
我在Microsoft Connect上开了一个缺陷报告,在这里。
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DataGrid ItemsSource="{Binding Employees, Mode=TwoWay}"
x:Name="tlv"
AutoGenerateColumns="False"
SelectionMode="Extended"
CanUserAddRows="true"
SelectionUnit="CellOrRowHeader">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding FirstName, Mode=TwoWay}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding LastName, Mode=TwoWay}"/>
<DataGridTextColumn Header="Salary" Binding="{Binding Salary, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}"/>
</DataGrid.Columns>
</DataGrid>
</Window>
代码后台:
Imports System.Collections.ObjectModel
Imports DataGridTest.Data
Class MainWindow
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.DataContext = Me
Employees = New ObservableCollection(Of Employee)(EmployeeRepository.GetFlatListData())
BindableSelectedItems = New ObservableCollection(Of Object)
End Sub
Private _employees As ObservableCollection(Of Employee)
Public Property Employees() As ObservableCollection(Of Employee)
Get
Return _employees
End Get
Set(ByVal value As ObservableCollection(Of Employee))
_employees = value
End Set
End Property
Private _bindableSelectedItems As ObservableCollection(Of Object)
Public Property BindableSelectedItems() As ObservableCollection(Of Object)
Get
Return _bindableSelectedItems
End Get
Set(value As ObservableCollection(Of Object))
'Set the new value of BindableSelectedItems
_bindableSelectedItems = value
End Set
End Property
Private _selectedEmployeeForSelectedItemsSimulation As Employee
Public Property SelectedEmployeeForSelectedItemsSimulation() As Employee
Get
Return _selectedEmployeeForSelectedItemsSimulation
End Get
Set(value As Employee)
'Set the new value of SelectedEmployeeForSelectedItemsSimulation
_selectedEmployeeForSelectedItemsSimulation = value
If _selectedEmployeeForSelectedItemsSimulation IsNot Nothing AndAlso BindableSelectedItems IsNot Nothing Then
BindableSelectedItems.Clear()
BindableSelectedItems.Add(value)
End If
End Set
End Property
End Class
员工类实现IDataErrorInfo接口:
Imports Microsoft.Practices.Prism.ViewModel
Imports System.Collections.ObjectModel
Imports System.ComponentModel
Namespace Data
Public Class Employee
Inherits NotificationObject
Implements IDataErrorInfo
Public Sub New()
End Sub
Public Sub New(ByVal fName As String, ByVal lName As String, ByVal salary As Double)
FirstName = fName
LastName = lName
Me.Salary = salary
End Sub
Private _firstName As String
Public Property FirstName() As String
Get
Return _firstName
End Get
Set(value As String)
'Set the new value of FirstName
_firstName = value
'Warn any Observers that the FirstName have changed.
RaisePropertyChanged(Function() Me.FirstName)
End Set
End Property
Private _lastName As String
Public Property LastName() As String
Get
Return _lastName
End Get
Set(value As String)
'Set the new value of LastName
_lastName = value
'Warn any Observers that the LastName have changed.
RaisePropertyChanged(Function() Me.LastName)
End Set
End Property
Private _isSelected As Boolean
Public Property IsSelected() As Boolean
Get
Return _isSelected
End Get
Set(value As Boolean)
'Set the new value of IsSelected
_isSelected = value
'Warn any Observers that the IsSelected have changed.
RaisePropertyChanged(Function() Me.IsSelected)
End Set
End Property
Private _salary As Double
Public Property Salary() As Double
Get
Return _salary
End Get
Set(value As Double)
'Set the new value of Salary
_salary = value
'Warn any Observers that the Salary have changed.
RaisePropertyChanged(Function() Me.Salary)
End Set
End Property
Public ReadOnly Property [Error] As String Implements IDataErrorInfo.Error
Get
Return String.Empty
End Get
End Property
Default Public ReadOnly Property Item(columnName As String) As String Implements IDataErrorInfo.Item
Get
If Me.Salary <= 0 Then
Return "The salary must be positive."
End If
Return String.Empty
End Get
End Property
End Class
End Namespace
到目前为止,一切都很好。然后,在添加新行后尝试更新薪资值时会发生以下情况:
1. 为什么会这样?我使用DataGrid的方式有问题吗? 2. 是否有解决方法?
[编辑] ... 和解决方法
我终于找到了一个看起来像是解决方法的东西,即使我仍然不知道我现在认为是Microsoft DataGrid中的错误的原因。
如果在数据网格列中指定了绑定模式,并且带有验证,则会出现此错误;如果我不指定绑定模式,则一切正常。
<DataGridTextColumn Header="Salary" Binding="{Binding Salary, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}"/>
我并不是很理解的是,据我所知默认的绑定模式是双向的...好吧,至少我解决了我的问题。
我在Microsoft Connect上开了一个缺陷报告,在这里。