所以我有一個WPF DataGrid
,它綁定到ObservableCollection
。該集合通過IDataErrorInfo
對其成員進行驗證。如果我以某種方式編輯某個單元格以使其無效,然後在按下回車鍵之前遠離它,然後返回並使其有效,單元格將停止顯示無效,但是,「!」在該行的頭部仍然存在,並且ToolTip
將引用先前的無效值。WPF DataGrid驗證錯誤不清除
回答
不使用Mode=TwoWay
對於DataGridTextColumns
解決了該問題的一個版本,但似乎這個問題也可能因爲其他原因而出現。
(任何人誰具有良好的解釋,爲什麼不使用Mode=TwoWay
的解決了這個擺在首位大概是接近解決這一問題)
同樣的事情只是發生在我身上了DataGridComboBoxColumn
如此我試圖深入一點。
問題不在於Control
中的Binding
,它在DataGridHeaderBorder
內顯示ErrorTemplate
。它將Visibility
綁定到Validation.HasError
,作爲祖先DataGridRow
(正如它應該做的那樣)並且該部分正在工作。
Visibility="{Binding (Validation.HasError),
Converter={StaticResource bool2VisibilityConverter},
RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}"/>
的問題是驗證錯誤不會從DataGridRow
清除一旦被解決。在我的版本的問題中,DataGridRow
從0錯誤開始。當我輸入一個無效值時,它有1個錯誤,所以非常好。但是當我解決這個錯誤時,它跳到了3個錯誤,所有這些錯誤都是一樣的。
在這裏,我試圖用一個DataTrigger
的ValidationErrorTemplate
設置爲{x:Null}
如果Validation.Errors.Count
沒有1.對於第一次迭代偉大的工作來解決它,但一旦我清除錯誤,第二次就又回來了。它不再有3個錯誤,它有7個!經過幾次迭代後,它大於10.
我也嘗試通過在BindingExpressions
上做UpdateSource
和UpdateTarget
手動清除錯誤,但沒有骰子。 Validation.ClearInvalid
也沒有任何影響。並希望通過該工具包中的源代碼並沒有得到我在任何地方:)
所以我沒有這個什麼好的解決方案,但我想我應該反正後我發現..
我唯一的「解決辦法」至今只是隱藏ErrorTemplate
在DataGridRowHeader
<DataGrid ...>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="ValidationErrorTemplate" Value="{x:Null}"/>
</Style>
</DataGrid.RowStyle>
<!-- ... -->
</DataGrid>
嘗試從每個綁定元素中刪除DataGridTextColumns
中的每個Mode=TwoWay
。
如果您看到類似Meleak錯誤越來越多,我很想知道你的錯誤收集如何被填充。在Meleaks版本中,他解決了無效數據後發現了三個錯誤(以及更多)。
在我的數據驗證代碼中,我刪除了以前的特定錯誤實例,然後在每次數據更改時重新添加。作爲參考,在這裏是一個示例:
的驗證水暖
#Region " Validation workers "
Private m_validationErrors As New Dictionary(Of String, String)
Private Sub AddError(ByVal ColName As String, ByVal Msg As String)
If Not m_validationErrors.ContainsKey(ColName) Then
m_validationErrors.Add(ColName, Msg)
End If
End Sub
Private Sub RemoveError(ByVal ColName As String)
If m_validationErrors.ContainsKey(ColName) Then
m_validationErrors.Remove(ColName)
End If
End Sub
Public ReadOnly Property [Error]() As String Implements System.ComponentModel.IDataErrorInfo.Error
Get
If m_validationErrors.Count > 0 Then
Return "Shipment data is invalid"
Else
Return Nothing
End If
End Get
End Property
Default Public ReadOnly Property Item(ByVal columnName As String) As String Implements System.ComponentModel.IDataErrorInfo.Item
Get
If m_validationErrors.ContainsKey(columnName) Then
Return m_validationErrors(columnName).ToString
Else
Return Nothing
End If
End Get
End Property
#End Region
A樓盤正在驗證
Private Sub OnZIPChanged()
Me.RemoveError("ZIP")
If _ZIP Is Nothing OrElse _ZIP.Trim = "" Then
Me.AddError("ZIP", "Please enter a ZIP Code")
Else
Select Case _ZIP.Length
Case 5
Case 10
Case Else
Me.AddError("ZIP", "Please enter a ZIP Code")
End Select
End If
OnPropertyChanged("CanShip")
End Sub
所以,當屬性更改處理程序運行時,如果在ValidationErrors存在錯誤字典中,將其刪除,然後檢查該值,如果不符合要求,則會向字典中添加錯誤。這有助於確保在該實體驗證錯誤字典中僅存在任何錯誤的一個實例。
集合中的所有錯誤都是完全相同的,一旦DataGridCell的內容出現驗證錯誤,它們就會在DataGrid內部填充到DataGridRow。不幸的是,您無法執行任何操作這個集合,但看看它在我的版本中的錯誤只是來自視圖模型'IDataErrorInfo'的實現。爲了深入瞭解問題所在,您可能需要訪問源代碼(而不是工具包中的源代碼他們在這方面的工作方式不同)。反射器雖然可以工作.. – 2011-09-22 21:45:30
嗯,是的,我沒有在ViewModel之前實現IDataErrorInfo。我在我的數據對象上做這件事,以便他們可以報告他們自己的驗證狀態(而不是從長遠來看真的很重要)。所以DataGrid填充了這些錯誤,並且它們從DataGridCell傳遞給它?我沒有聽說過這個(我絕不是專家)。這是香草.NET DataGrid嗎? – CodeWarrior 2011-09-23 14:00:50
我的情況是這樣的:
- 模型實現了基於WPF DataGrid Practical Examples -Validation with IDataErrorInfo
IDataErrorInfo
定製行驗證規則,即結合使用IDataErrorInfo的從模型的所有錯誤。
<DataGrid.RowValidationRules> <local:RowDataInfoValidationRule ValidationStep="UpdatedValue" /> </DataGrid.RowValidationRules>
ValidatesOnDataErrors=True
,ValidatesOnExceptions=True
,NotifyOnValidationError=True
內的結合(我開始)
這導致了多個訪問我的驗證引擎和eventualy在不一致的狀態我DataGrid
(上排的錯誤通知即使在行有效時也是如此)。
的解決方案是從結合(點3)
我建議通過Clearing a DataGrid row validation error讀取太除去開關。
我的解決方法是從每個數據網格列表中的綁定聲明中刪除屬性UpdateSourceTrigger =「LostFocus」。
我的解決方法是不使用Validation.Errors,但使用DataGridRow.Item屬性。如果DataGrid綁定到實現IDataErrorInfo接口的業務對象,則可以添加IsNotValid屬性(或IsValid),並確保Error屬性返回與該對象關聯的所有錯誤。然後自定義默認樣式DataGridRowHeader:
<Style x:Key="{x:Type DataGridRowHeader}" TargetType="{x:Type DataGridRowHeader}">
...
<Control SnapsToDevicePixels="false"
Visibility="{Binding RelativeSource={RelativeSource
AncestorType={x:Type DataGridRow}},
Path=Item.IsNotValid, Converter={StaticResource
Bool2VisibilityConverter}}"
Template="{Binding RelativeSource={RelativeSource
AncestorType={x:Type DataGridRow}},
Path=ValidationErrorTemplate}" />
...
</Style>
而且在DataGridRow風格定製ValidationErrorTemplate,使其顯示從DataGridRow.Item.Error媒體資源相關聯的錯誤消息。
我的解決辦法來實現自定義行確認反饋,根據要自定義行確認反饋部分類似於this page。行錯誤然後適當地消失。
(我還加RowHeaderWidth="20"
到DataGrid
定義,避免了表移到第一時間感嘆號出現的權利。)
在我的情況下,它的工作一切都很好,當我們使用DataGrid WPF3.5版本。我們升級到4.0,然後停止重置。在SO,谷歌等搜索後,我碰巧遇到了我的解決方案。 設置UpdateSourceTrigger = PropertyChanged在DataGridTextColumn中的綁定爲我解決了它。
我剛剛意識到紅色感嘆號不會清除將其設置爲正確的值。
在我來說,我不得不從綁定定義
UpdateSourceTrigger=PropertyChanged
對我來說,除去它的工作原理與這兩個定義:
<DataGridTextColumn
Header="Time, min"
x:Name="uiDataGridTextColumnTime"
Width="Auto"
CellStyle="{StaticResource ResourceKey=DataGridCellText}"
IsReadOnly="False">
<DataGridTextColumn.Binding>
<Binding Path="fTime" StringFormat="{}{0:0.00}">
<Binding.ValidationRules>
<Validation:CellDataInfoValidationRule ValidationStep="UpdatedValue"/>
</Binding.ValidationRules>
</Binding>
</DataGridTextColumn.Binding>
而且
<DataGridTextColumn
Header="Time, min"
x:Name="uiDataGridTextColumnTime"
Width="Auto"
CellStyle="{StaticResource ResourceKey=DataGridCellText}"
Binding="{Binding fTime, StringFormat={}\{0:0.00\}, ValidatesOnDataErrors=True}"
IsReadOnly="False">
驗證:CellDataInfoValidationRule是自定義類&得到它這裏
public class CellDataInfoValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
// obtain the bound business object
BindingExpression expression = value as BindingExpression;
IDataErrorInfo info = expression.DataItem as IDataErrorInfo;
// determine the binding path
string boundProperty = expression.ParentBinding.Path.Path;
// obtain any errors relating to this bound property
string error = info[boundProperty];
if (!string.IsNullOrEmpty(error))
{
return new ValidationResult(false, error);
}
return ValidationResult.ValidResult;
}
}
而且你數據對象,我不使用IDataErrorInfo
或INotifyDataErrorInfo
和我的解決辦法是改變我的綁定必須實現IDataErrorInfo的
UpdateSourceTrigger="PropertyChanged"
到UpdateSourceTrigger="LostFocus"
這是唯一的東西
如果你是usin摹ValidationRules在DataGrid列確定指標和你需要的驗證規則時曾經屬性的變化(在UI或屬性)看看你的ValidationRule
XAML設定例ValidatesOnTargetUpdated="True"
運行:
<DataGridTextColumn Header="Name"
CellStyle="{StaticResource DGCellStyle}"
ElementStyle="{StaticResource DGTextColValidationStyle}"
EditingElementStyle="{StaticResource DGTextColEditValidationStyle}">
<DataGridTextColumn.Binding>
<Binding Path="Name" UpdateSourceTrigger="LostFocus">
<Binding.ValidationRules>
<ValidationResource:YourValidationRule ValidationStep="UpdatedValue" ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
我與RowHeader錯誤模板不會消失相同的問題。我正在使用INotifyDataErrorInfo。在Fredrik Hedblad的研究之後,我提出了一個解決方法;我已經修改了DataGridRowHeader模板使用MultiBinding爲ValidationErrorTemplate知名度:
<Style x:Key="DataGridRowHeaderStyle" TargetType="{x:Type DataGridRowHeader}">
<!--<Setter Property="Background" Value="{DynamicResource {ComponentResourceKey TypeInTargetAssembly=Brushes:BrushesLibrary1,
ResourceId=HeaderBrush}}"/>-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRowHeader}">
<Grid>
<Microsoft_Windows_Themes:DataGridHeaderBorder BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
IsPressed="{TemplateBinding IsPressed}" IsHovered="{TemplateBinding IsMouseOver}"
IsSelected="{TemplateBinding IsRowSelected}" Orientation="Horizontal"
Padding="{TemplateBinding Padding}" SeparatorBrush="{TemplateBinding SeparatorBrush}"
SeparatorVisibility="{TemplateBinding SeparatorVisibility}">
<StackPanel Orientation="Horizontal">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"
Width="15"/>
<Control SnapsToDevicePixels="false"
Template="{Binding ValidationErrorTemplate, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}">
<Control.Visibility>
<MultiBinding Converter="{StaticResource ValidationConverter}">
<Binding Path="(Validation.HasError)" RelativeSource="{RelativeSource AncestorType={x:Type DataGridRow}}"/>
<Binding Path="DataContext.HasErrors" RelativeSource="{RelativeSource AncestorType={x:Type DataGridRow}}"/>
</MultiBinding>
</Control.Visibility>
<!-- Original binding below -->
<!--Visibility="{Binding (Validation.HasError), Converter={StaticResource bool2VisibilityConverter},
RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}">-->
</Control>
</StackPanel>
</Microsoft_Windows_Themes:DataGridHeaderBorder>
<Thumb x:Name="PART_TopHeaderGripper" Style="{StaticResource RowHeaderGripperStyle}" VerticalAlignment="Top"/>
<Thumb x:Name="PART_BottomHeaderGripper" Style="{StaticResource RowHeaderGripperStyle}" VerticalAlignment="Bottom"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
這依賴於具有變化的通知「HasErrors」屬性的綁定對象。在我的項目中,我確保通過在EndEdit事件中引發HasErrors的PropertyChanged來更新HasErrors屬性。
我找到了適合我的最佳答案。請清除您的DataGrid
的RowValidationErrorTemplate
。
代碼
YourGrid.RowValidationErrorTemplate = new ControlTemplate();
在XAML
<DataGrid.RowValidationErrorTemplate> <ControlTemplate> </ControlTemplate> </DataGrid.RowValidationErrorTemplate>`
然後讓你自己行驗證錯誤模板。
如果您的數據產品INotifyPropertyChanged的
((INotifyPropertyChanged)i).PropertyChanged += this.i_PropertyChanged;`
然後
private void i_PropertyChanged(object sender, PropertyChangedEventArgs e) { this.Dispatcher.BeginInvoke(new Action(() => { var row = this.ItemContainerGenerator.ContainerFromItem(sender) as DataGridRow; if (row == null) return; var Errs = IsValid(row); if (Errs.Count == 0) row.Header = null; else { // Creatr error template var gg = new Grid { ToolTip = "Error Tooltip" }; var els = new Ellipse { Fill = new SolidColorBrush(Colors.Red), Width = row.FontSize, Height = row.FontSize }; var tb = new TextBlock { Text = "!", Foreground = new SolidColorBrush(Colors.White), HorizontalAlignment = HorizontalAlignment.Center, FontWeight = FontWeights.Bold }; gg.Children.Add(els); gg.Children.Add(tb); row.Header = gg; } }), System.Windows.Threading.DispatcherPriority.ApplicationIdle); }
寫自己的IsValid的方法,方式你喜歡
好了,經過一番工作協同的解決方案的改變工作f或者我,我這是怎麼實現的吧:
<Style x:Key="{x:Type DataGridRowHeader}" TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Control SnapsToDevicePixels="true"
Visibility="{Binding RelativeSource={RelativeSource
AncestorType={x:Type DataGridRow}},
Path=Item.HasErrors, Converter={StaticResource
BooleanToVisibilityConverter }}"
Template="{Binding RelativeSource={RelativeSource
AncestorType={x:Type DataGridRow}},
Path=ValidationErrorTemplate}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
不要忘記引用BooleanToVisibilityConverter:
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
就行樣式不(還)看作爲默認的一樣好,我在做這個工作。
編輯:PLZ幫助這裏
WRT你的「編輯」...如果你有一個新的問題,請點擊[問問題](// stackoverflow.com/questions/ask)按鈕。您始終可以參考此答案的上下文......但將您的代碼包含在新問題中。 – Mogsdad 2015-09-01 21:13:10
我已經使用這個技術,它與RowValidationRules廢除,轉而使用性能驗證在視圖模型。這需要靜態變量和數據註解:
//uses Prism.MVVM for BindableBase and INotifyDataErrorInfo
private static int _xxStartNo;
private static int _xxEndNo;
// in property getter/setter
private int _startNo;
[CustomValidation(typeof(YourModel), "ValidateStartNoRange")]
public int StartNo
{
get
{
_xxStartNo=_startNo;
return _startNo;
}
set
{
..........
ValidateProperty("StartNo")
}
}
.......
public static ValidationResult ValidateStartNoRange(int number)
{
if(number > _xxEndNo)
{
return ValidationResult("Start No must be less than End No.";
}
return ValidationResult.Success;
}
- 1. WPF驗證:清除所有驗證錯誤
- 2. WPF DataGrid行驗證錯誤計數
- 3. 驗證錯誤消息未清除
- 4. 如何清除jquery驗證錯誤
- 5. WPF驗證錯誤
- 6. WPF DataGrid - 驗證建議
- 7. WPF Datagrid跨行驗證
- 8. Force DataGrid列驗證(WPF)
- 9. 防止在WPF DataGrid上發生驗證錯誤時保存
- 10. WPF DataGrid單元格與驗證錯誤樣式
- 11. wpf mvvm錯誤驗證
- 12. 檢測WPF驗證錯誤
- 13. jQuery的表單驗證 - 正確提交不清除錯誤
- 14. jQuery驗證:重置錯誤消息,但不清除表單
- 15. DataGrid列驗證錯誤模板
- 16. DataGrid驗證顯示錯誤問題
- 17. jquery驗證插件 - 顯示錯誤與清除錯誤的不同處理
- 18. 清除datagrid在wpf中的Itemssource
- 19. SQLite Datagrid驗證
- 20. 清除錯誤消息或使用jQuery驗證插件重置驗證
- 21. 如何在使用jQuery表單驗證插件時「清除」驗證錯誤?
- 22. WPF的DataGrid驗證問題 - MVVM
- 23. WPF DataGrid |隱藏行驗證列
- 24. 當綁定到DataView時WPF DataGrid驗證
- 25. 清除所有表單域驗證錯誤在Django
- 26. 如何清除Eclipse中的驗證錯誤?
- 27. 帶有ImageFields的ModelForm,如果驗證錯誤未正確清除
- 28. jquery驗證器:何時清除自定義錯誤圖標
- 29. 驗證/清除使用Dojo
- 30. 清除驗證摘要mvc3
+1這實在是煩人:( – surfen 2011-12-11 23:55:53
如果我不使用'模式= TwoWay'文格不可編輯了和'DataGridTextColumn.EditingElementStyle'是永遠 – bitbonk 2014-04-15 14:03:59