【发布时间】:2020-03-18 15:36:07
【问题描述】:
我有一个类SerialItem 的Observable 集合SerialList,其中包含一个字符串属性Number,我将DataGrid 的ItemsSource 绑定到该集合。目的是让用户查看一些预先存在的字符串值,并添加一些新的,通过 wpf ValidationRule 进行验证。当用户输入无效字符串并按“Enter”或跳出标签或单击另一行时,验证失败就好了,呈现典型的错误模板。在没有进一步编辑的情况下按“Escape”,“错误”的值会被清空。当现有或已批准的单元格值更改为“错误”值并且用户按“Enter”时,问题就开始了,验证再次按预期失败,但在此之后立即按“Escape”,“错误”值仍然存在,如如果已通过验证。
谁能解释或指出为什么会发生这种情况,或者解决这个问题?
我使用的代码如下:
MainWindow.xaml
<Window x:Class="WpfApp8.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:WpfApp8"
mc:Ignorable="d"
Title="MainWindow" Height="330" Width="200">
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<DockPanel>
<DataGrid DockPanel.Dock="Top" ItemsSource="{Binding SerialList}"
AutoGenerateColumns="False" RowStyle="{StaticResource RowStyle}">
<DataGrid.RowValidationRules>
<local:SerialValidationRule ValidationStep="UpdatedValue"/>
</DataGrid.RowValidationRules>
<DataGrid.Columns>
<DataGridTextColumn Header="Serial" Width="*" IsReadOnly="false" Binding="{Binding Path=Number, UpdateSourceTrigger=LostFocus}">
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
</Window>
MainWindowViewModel.cs
using System.Collections.ObjectModel;
namespace WpfApp8
{
public class MainWindowViewModel : ViewModelBase
{
public LicenseModel myModel;
private ObservableCollection<SerialItem> m_SerialList = new ObservableCollection<SerialItem>();
public MainWindowViewModel()
{
myModel = new LicenseModel {
Serial_numbers = new Serial_numbers {
SerialNumbers = new ObservableCollection<SerialItem> { new SerialItem { Number = "111111"}, new SerialItem { Number = "222222" } }
}
};
SerialList = myModel.Serial_numbers.SerialNumbers;
}
public ObservableCollection<SerialItem> SerialList
{
get
{
return m_SerialList;
}
set
{
m_SerialList = value;
myModel.Serial_numbers.SerialNumbers = m_SerialList;
RaisePropertyChanged("SerialList");
}
}
private void OnSerialListCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
RaisePropertyChanged("SerialList");
}
}
}
DataModel.cs
using System.Collections.ObjectModel;
using System.Xml.Serialization;
namespace WpfApp8
{
[XmlRoot(ElementName = "serial_numbers")]
public class Serial_numbers
{
[XmlElement(ElementName = "number")]
public ObservableCollection<SerialItem> SerialNumbers { get; set; }
}
public class SerialItem
{
public string Number { get; set; }
}
public class LicenseModel
{
[XmlElement(ElementName = "serial_numbers")]
public Serial_numbers Serial_numbers { get; set; }
}
}
SerialValidationRule.cs
using System.Globalization;
using System.Windows.Controls;
namespace WpfApp8
{
public class SerialValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
var bindExpressions = value as System.Windows.Data.BindingGroup;
var bindingitem = bindExpressions.Items[0];
var serial = bindingitem as SerialItem;
if (serial.Number == null)
{
return new ValidationResult(false, "Serial number cannot be empty");
}
if (serial.Number.Length != 6)
{
return new ValidationResult(false, "Serial number has to be 6 characters long!");
}
return new ValidationResult(true, "");
}
}
}
App.xaml
<Application x:Class="WpfApp8.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="RowStyle" TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)/ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Application.Resources>
</Application>
【问题讨论】:
-
很可能与您的基类 ViewModelBase 相关。您应该在某处发布一个最小的复制项目,而不是在此处放置文件。
-
这是我可以提供的关于我的问题的绝对最少信息量,以便愿意提供帮助的人只需获取一些代码并立即进行调查......
-
我尝试过使用“自制”ViewModelBase 类,但也尝试过使用 MVVMLight 库,没有任何区别...
标签: wpf validation mvvm datagrid