DataGrid,BlankRow和RowValidationRules问题。 [英] DataGrid, BlankRow and RowValidationRules Problem.
问题描述
大家好,
我对dataGrid BlankRow和RowValidationRules有一个问题(Framework 4.7.1,但我认为它无关紧要),详细说明:
简单类(Hello),只有一个属性(HelloString)作为字符串,验证类(HelloValidation),当HelloString值为"Hello baby"时Validate方法返回New ValidationResult(False,"Ko")。
我有一个公共属性(HelloCollection)作为ObservableCollection(Of Hello),在Window_Loaded事件中我将项目添加到集合中。
在xaml中有一个DataGrid,其ItemsSource =" {Binding HelloCollection}"的AutoGenerateColumns = QUOT假QUOT;和一个带有Binding =" {Binding HelloString}"的DataGridTextColumn,在行的底部有一个空行(由
datagrid自动添加)以插入新项;在xaml中有一个按钮可以从集合中删除HelloString值为"Hello baby"的项目。
一切正常,除非我写"Hello baby"。 (datagrid正确地使用红色感叹号发出警报)而不是更正值我按下按钮删除使数据网格处于ValidationError状态的项目(validationError
状态正确冻结所有有效行并使可编辑仅行使用validationError),在这种情况下,正确删除了具有无效值的行,但数据网格继续处于ValidationError状态(如果您之前在空白行中写入"Hello baby"
,则新的空白行不会(b)
代码背后:
Hello everyone,
I have a problem with dataGrid BlankRow and RowValidationRules (Framework 4.7.1 but I think it is indifferent), in detail:
simple class (Hello) with only one property (HelloString) as string, validation class (HelloValidation) and when HelloString value is "Hello baby" the Validate method Return New ValidationResult(False, "Ko").
I have a public property (HelloCollection) as ObservableCollection(Of Hello) and at Window_Loaded event I add items to collection.
In xaml there is a DataGrid with ItemsSource="{Binding HelloCollection}" AutoGenerateColumns="False" and one DataGridTextColumn with Binding="{Binding HelloString}", at bottom of rows there is a blank row (added automatically by
datagrid) to insert new item; plus in xaml there is a button to remove from collection the item with HelloString value at "Hello baby".
Everything works well, except when I write "Hello baby" (datagrid correctly make alert with red exclamation mark) and I instead of correct the value I press the button to remove the item that make the datagrid in ValidationError state (validationError
state correctly freezes all valid rows and make editable only the row with validationError), in this case the row with invalid value is correctly removed, but the datagrid continues to be in ValidationError state (and if you previously write "Hello baby"
in the blank row, the new blank row not appear).
Code behind:
Imports System.ComponentModel
Imports System.Globalization
Imports System.Runtime.CompilerServices
Class MainWindow
Implements INotifyPropertyChanged
Private helloCollection_ As ObjectModel.ObservableCollection(Of Hello)
Public Property HelloCollection As ObjectModel.ObservableCollection(Of Hello)
Get
Return helloCollection_
End Get
Set(value As ObjectModel.ObservableCollection(Of Hello))
helloCollection_ = value
NotifyPropertyChanged()
End Set
End Property
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
HelloCollection = New ObjectModel.ObservableCollection(Of Hello)
HelloCollection.Add(New Hello With {.HelloString = "Hello 1"})
HelloCollection.Add(New Hello With {.HelloString = "Hello 2"})
HelloCollection.Add(New Hello With {.HelloString = "Hello 3"})
End Sub
Private Sub btnRemoveErrorItemInCollection_Click(sender As Object, e As RoutedEventArgs)
Dim itemToRemove = From tmp In HelloCollection Where tmp.HelloString = "Hello baby"
If itemToRemove.Count > 0 Then HelloCollection.Remove(itemToRemove(0))
End Sub
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
Public Class Hello
Implements INotifyPropertyChanged
Private helloString_ As String
Public Property HelloString As String
Get
Return helloString_
End Get
Set(value As String)
helloString_ = value
NotifyPropertyChanged()
End Set
End Property
Public Sub New()
End Sub
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
Public Class HelloValidation
Inherits ValidationRule
Public Overrides Function Validate(value As Object, cultureInfo As CultureInfo) As ValidationResult
Dim bindingGrp As BindingGroup = value
Dim ogg As Hello = bindingGrp.Items(0)
If ogg.HelloString = "Hello baby" Then
Return New ValidationResult(False, "Ko")
Else
Return New ValidationResult(True, "Ok")
End If
End Function
End Class
XAML:
XAML:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" DataContext="{Binding RelativeSource={RelativeSource Self}}" Loaded="Window_Loaded">
<Grid>
<DataGrid x:Name="dtgHello" Margin="0,0,0,50" ItemsSource="{Binding HelloCollection}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn x:Name="txtHelloString" Header="Hello String" Binding="{Binding HelloString}" />
</DataGrid.Columns>
<DataGrid.RowValidationRules>
<local:HelloValidation ValidationStep="UpdatedValue"/>
</DataGrid.RowValidationRules>
</DataGrid>
<Button x:Name="btnRemoveErrorItemInCollection" VerticalAlignment="Bottom" Content="Remove item in error from collection" Click="btnRemoveErrorItemInCollection_Click" />
</Grid>
</Window>
&NBSP;&NBSP;
可能的解决方法:
possible workaround:
Private Sub btnRemoveErrorItemInCollection_Click(sender As Object, e As RoutedEventArgs)
Dim itemToRemove = From tmp In HelloCollection Where tmp.HelloString = "Hello baby"
If itemToRemove.Count > 0 Then HelloCollection.Remove(itemToRemove(0))
dtgHello.ItemsSource = Nothing
dtgHello.ItemsSource = HelloCollection
End Sub
但是我认为如果收集有很多行,那么对于cpu来说太重了&b;
任何其他解决方法?
谢谢和抱歉我的英文不好。
but I think is too heavy for the cpu if collection have many rows
any other workaround?
thanks and sorry for my bad english.
推荐答案
嗨 Nick Hola,
Hi Nick Hola,
据我所知,WPF不会自动清除验证信息,在解决验证错误之前,DataGrid不会退出单元格编辑模式。删除源
值后,DataGridRow仍存在于DataGrid的Items属性中。
As far as I know, WPF does not clean the validation information automatically, and the DataGrid will not exit cell editing mode until the validation error is resolved. The DataGridRow is still existing in the Items property of the DataGrid after the source value is deleted.
简单的解决方案是调用DataGrid.Items.Refresh();
The simple solution is to call the DataGrid.Items.Refresh();
Private Sub btnRemoveErrorItemInCollection_Click(sender As Object, e As RoutedEventArgs)
Dim itemToRemove = From tmp In HelloCollection Where tmp.HelloString = "Hello baby"
If itemToRemove.Count > 0 Then HelloCollection.Remove(itemToRemove(0))
dtgHello.Items.Refresh()
'dtgHello.ItemsSource = Nothing
'dtgHello.ItemsSource = HelloCollection
End Sub
您上面发布的解决方案(重新绑定itemsource)是一种避免此问题的方法。
The solution you have post above (rebing the itemsource) is a way to avoid the issue.
但是,通常,当我们验证一些值时。在客户输入正确的值之前,我们不会退出单元格编辑模式。它符合验证的初衷。
But, usually, when we validate some values. We will not exit cell editing mode until the customer has input the correct values. It meets the original intention to the verification.
最好的问候,
Best Regards,
Yong Lu
这篇关于DataGrid,BlankRow和RowValidationRules问题。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!