是否有可能在编辑模式下停止使用验证错误--由绑定对象的属性设置器中的异常引起--从失去焦点直到用户( a)纠正该错误,或者( b)通过按'Esc‘来恢复其更改?
此外,虽然我可以显示行的验证模板,但我似乎无法为DataGridCell本身触发它。
这是我们的测试风格。这很管用..。
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
<Setter Property="Background" Value="Yellow"/>
</Trigger>
</Style.Triggers>
</Style>这不是..。
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>以下是我们的专栏:
<DataGrid.Columns>
<DataGridTextColumn x:Name="NameColumn"
Header="Name"
Binding="{Binding Name, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}"
Width="*" />
<DataGridTextColumn x:Name="ValueColumn"
Header="Value"
Binding="{Binding Value, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}"
Width="*" />
</DataGrid.Columns>发布于 2015-09-18 08:26:02
是的,这是可能的。例如,我们必须检查可以生成错误的HasErrors属性,并相应地设置其值。
这个答案使用了我在这里发布的解决方案中提出的概念:
WPF MVVM Validation DataGrid and disable CommandButton
DataGridCellTemplate xaml代码:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox VerticalAlignment="Stretch" VerticalContentAlignment="Center" Loaded="TextBox_Loaded" PreviewLostKeyboardFocus="TextBox_PreviewLostKeyboardFocus" PreviewKeyUp="TextBox_PreviewKeyUp">
<TextBox.Triggers>
</TextBox.Triggers>
<TextBox.Text>
<Binding Path="ID" UpdateSourceExceptionFilter="ReturnExceptionHandler" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True" ValidatesOnExceptions="True" >
<Binding.ValidationRules>
<v:CustomValidRule ValidationStep="ConvertedProposedValue"></v:CustomValidRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>MainWindow.cs
ViewModel vm = new ViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = vm;
}
// This is wrong and will result in StackOverflow exception
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
if (vm.HasErrors)
{
TextBox b = (TextBox)sender;
b.Focus();
}
}
private void TextBox_PreviewLostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
TextBox b = (TextBox)sender;
if (vm.HasErrors)
{
e.Handled = true;
b.Focus();
b.CaptureMouse();
}
else {
e.Handled = false;
b.ReleaseMouseCapture();
}
}
private void TextBox_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Escape)
{
TextBox b = (TextBox)sender;
b.Undo();
}
}现在,我们需要在这些地方检查错误并设置ViewModel的ViewModel属性。
这些错误可以按这个顺序在三个层次上产生;
在更新值时由绑定引擎引发的异常,
b.在值到达ViewModel之前进行自定义验证。
c.在ViewModel中根据DataBase或其他东西进行验证。
当输入需要数字的字符时,通常会遇到这种情况。这是使用UpdateSourceExceptionFilter处理的。输出窗口显示如下所示:
System.Windows.Data Error: 7 : ConvertBack cannot convert value 'a' (type 'String'). BindingExpression:Path=ID; DataItem='Class1' (HashCode=66068479); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') FormatException:'System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)我们的UpdateSourceExceptionFilterCallback :这是我们在TextBox中设置的。
object ReturnExceptionHandler(object bindingExpression, Exception exception)
{
vm.HasErrors = true;
return "This is from the UpdateSourceExceptionFilterCallBack.";
}这是我们用我们插入的验证规则来做的。但是我们的ViewModel将如何了解这些规则呢?我们将维护对这些规则的观察,并将事件处理程序附加到这些规则中,这样他们就可以通知他们的ViewModel,就像我们实现INotifyPropertyChanged通知绑定引擎一样。我们将规则添加到vm中,如下所示,MainWindow.cs
private void TextBox_Loaded(object sender, RoutedEventArgs e)
{
Collection<ValidationRule> rules= ((TextBox)sender).GetBindingExpression(TextBox.TextProperty).ParentBinding.ValidationRules;
foreach (ValidationRule rule in rules)
vm.Rules.Add(rule);
}ViewModel.cs
void Rules_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
foreach (var v in e.NewItems)
((IViewModelUIRule)v).ValidationDone += ViewModel_ValidationDone;
}
void ViewModel_ValidationDone(object sender, ViewModelUIValidationEventArgs e)
{
HasErrors = e.IsValid;
}在最后一级检查错误。我们处理集合中所有绑定对象的PropertyChanged事件。我们绑定到DataGrid的这个集合。
void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (((Class1)sender).ID > 7)
HasErrors = true;
else
HasErrors = false;
}2.此外,虽然我可以显示行的验证模板,但我似乎无法为DataGridCell本身触发它。
DataGridRow有ValidationErrorTemplate,而DataGridCell没有。
https://stackoverflow.com/questions/32635618
复制相似问题