我在 RowValidationRules 标记内有一个带有验证规则的DataGrid。
我想要的是仅在没有验证错误的情况下更新绑定属性,否则应保留旧值。
XAML:
<DataGrid
Margin="10"
CanUserAddRows="True"
CanUserDeleteRows="True"
AutoGenerateColumns="False"
IsReadOnly="False"
ItemsSource="{Binding Source={x:Static services:SharedPropertiesProvider.Instance}, Path=Aliases, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
>
<DataGrid.RowValidationRules>
<validation:AliasValidation />
</DataGrid.RowValidationRules>
<DataGrid.Columns>
<DataGridTextColumn Width="30*" Header="Alias" Binding="{Binding Key, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
<DataGridTextColumn Width="70*" Header="Path" Binding="{Binding Value, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Command="ApplicationCommands.Delete" Width="20" Height="20">
<Button.Content>
<Image Margin="2" Source="/WinLogInspector;component/Assets/1441392968_f-cross_256.png" />
</Button.Content>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
验证类:
class AliasValidation : ValidationRule {
public override ValidationResult Validate(object value, CultureInfo cultureInfo) {
if (((BindingGroup)value).Items.Count > 0)
{
Alias item = (value as BindingGroup).Items[0] as Alias;
if (item != null)
{
string aliasPattern = @"^[a-zA-Z]+[a-zA-Z0-9]*$";
string pathPattern = @"^[a-zA-Z0-9\\/@:_\-;]+$";
string key = item.Key ?? String.Empty;
string path = item.Value ?? String.Empty;
bool isValidAlias = Regex.IsMatch(key, aliasPattern);
bool isValidPath = Regex.IsMatch(path, pathPattern);
if (isValidAlias && isValidPath)
return ValidationResult.ValidResult;
else
return new ValidationResult(false, "Invalid alias / path");
}
}
return ValidationResult.ValidResult;
} }
viewmodel中的属性:
public ObservableCollection<Alias> Aliases { get; set; }
class Alias
{
public string Key { get; set; }
public string Value { get; set; }
}
因此,如果我尝试从viewmodel执行任何命令,我可以看到 Aliases 属性具有无效行。 我怎样才能消毒呢?
答案 0 :(得分:1)
public string key;
public string Key {
get { return key; }
set
{
if (key != value && this["KeyDisplay"] == string.Empty)
{
key = value;
NotifyPropertyChanged("Key");
}
}
}
public string _value;
public string Value
{
get { return _value; }
set
{
if (_value != value && this["ValueDisplay"] == string.Empty)
{
_value = value;
NotifyPropertyChanged("Value");
}
}
}
public string keyDisplay;
public string KeyDisplay
{
get { return keyDisplay; }
set
{
if (keyDisplay != value)
{
keyDisplay = value;
Key = value;
NotifyPropertyChanged("KeyDisplay");
}
}
}
public string valueDisplay;
public string ValueDisplay
{
get { return valueDisplay; }
set
{
if (valueDisplay != value)
{
valueDisplay = value;
Value = value;
NotifyPropertyChanged("ValueDisplay");
}
}
}
public string this[string columnName]
{
get
{
if (columnName == nameof(KeyDisplay) || columnName == nameof(ValueDisplay))
{
string aliasPattern = @"^[a-zA-Z]+[a-zA-Z0-9]*$";
string pathPattern = @"^[a-zA-Z0-9\\/@:_\-;]+$";
string key = KeyDisplay ?? String.Empty;
string path = ValueDisplay ?? String.Empty;
bool isValidAlias = Regex.IsMatch(key, aliasPattern);
bool isValidPath = Regex.IsMatch(path, pathPattern);
if (isValidAlias && isValidPath)
return string.Empty;
else
return "Invalid alias / path";
}
return string.Empty;
}
}
这是原始答案,完全不正确!验证会阻止更新与绑定相关联的属性。我猜你的属性正在设置,即使它们没有通过验证是因为这些属性实际上没有被验证。您只对ItemsControl ItemsSource属性启用NotifyOnValidationError=True
验证。
使用MVVM我真的建议使用IDataErrorInfo并在ViewModel或Model中进行验证 - 验证与显示无关,并且在我看来不属于视图。
class Alias : IDataErrorInfo
{
public string Key { get; set; }
public string Value { get; set; }
public string this[string columnName]
{
get
{
if (columnName == nameof(Key) || columnName == nameof(Value))
{
string aliasPattern = @"^[a-zA-Z]+[a-zA-Z0-9]*$";
string pathPattern = @"^[a-zA-Z0-9\\/@:_\-;]+$";
string key = Key ?? String.Empty;
string path = Value ?? String.Empty;
bool isValidAlias = Regex.IsMatch(key, aliasPattern);
bool isValidPath = Regex.IsMatch(path, pathPattern);
if (isValidAlias && isValidPath)
return string.Empty;
else
return "Invalid alias / path";
}
return string.Empty;
}
}
public string Error
{
get
{
return string.Empty;
}
}
}
它还使您可以更灵活地检查多个属性是否有效,因为您可以访问绑定逻辑中的整个数据模型。我认为使用ValidationRules,您可能不得不使用多重绑定或其他东西。
如果你在Key和Value绑定中使用验证时坚持使用ValidationRules:Binding="{Binding Key, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True...}">
他们不应该在失败时更新。