我创建了一个非常简单的新项目,仅测试Microsoft
WPF DataGrid行为.没有其他涉及,我只使用标准的DataGrid:
<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
Employee类,它实现了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
到现在为止还挺好.然后,当我在添加新行后尝试更新工资值时会发生以下情况:
该值重置为0!
>为什么这样做?我使用DataGrids的方式出了什么问题?
>有解决方法吗?
[编辑] ……和替代方法
我终于发现了看起来像是一种解决方法,即使我仍然不知道我现在认为是Microsoft DataGrid中的错误的原因.
如果在带有验证的datagrid列中指定了绑定模式,则会发生错误;如果相反我没有指定绑定模式,一切都很好.
<DataGridTextColumn Header="Salary" Binding="{Binding Salary,UpdateSourceTrigger=LostFocus}"/>
我不太明白的是,据我所知,默认绑定模式是TwoWay ……好吧,至少我解决了我的问题.