У меня есть пользовательский ValidationRule, который требует доступа к ViewModel для проверки поставляемого значения в сочетании с другими свойствами ViewModel. Я ранее пытался добиться этого, используя ValidationGroup, но отказался от этой идеи, поскольку код, который я изменяю, нуждался бы в большом количестве рефакторинга, чтобы включить этот маршрут.
Я нашел поток в группе новостей, который показал способ привязки DataContext элемента управления, в котором ValidationRule выполняется для этого ValidationRule через промежуточный класс, унаследованный от DependencyObject, но я не могу заставить его привязываться.
Помогает ли кто-нибудь?
My ValidationRule выглядит следующим образом:
class TotalQuantityValidator : CustomValidationRule {
public TotalQuantityValidator()
: base(@"The total number must be between 1 and 255.") {
}
public TotalQuantityValidatorContext Context { get; set; }
public override ValidationResult Validate(object value, CultureInfo cultureInfo) {
ValidationResult validationResult = ValidationResult.ValidResult;
if (this.Context != null && this.Context.ViewModel != null) {
int total = ...
if (total <= 0 || total > 255) {
validationResult = new ValidationResult(false, this.ErrorMessage);
}
}
return validationResult;
}
}
CustomValidationRule определяется следующим образом:
public abstract class CustomValidationRule : ValidationRule {
protected CustomValidationRule(string defaultErrorMessage) {
this.ErrorMessage = defaultErrorMessage;
}
public string ErrorMessage { get; set; }
}
TotalQuantityValidatorContext определяется следующим образом:
public class TotalQuantityValidatorContext : DependencyObject {
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(@"ViewModel",
typeof(MyViewModel), typeof(TotalQuantityValidatorContext),
new PropertyMetadata {
DefaultValue = null,
PropertyChangedCallback = new PropertyChangedCallback(TotalQuantityValidatorContext.ViewModelPropertyChanged)
});
public MyViewModel ViewModel {
get { return (MyViewModel)this.GetValue(TotalQuantityValidatorContext.ViewModelProperty); }
set { this.SetValue(TotalQuantityValidatorContext.ViewModelProperty, value); }
}
private static void ViewModelPropertyChanged(DependencyObject element, DependencyPropertyChangedEventArgs args) {
}
}
И все это используется таким образом...
<UserControl x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:val="clr-namespace:Validators" x:Name="myUserControl">
<TextBox Name="myTextBox">
<TextBox.Text>
<Binding NotifyOnValidationError="True" Path="myViewModelProperty" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<val:TotalQuantityValidator>
<val:TotalQuantityValidator.Context>
<val:TotalQuantityValidatorContext ViewModel="{Binding ElementName=myUserControl, Path=DataContext}" />
</val:TotalQuantityValidator.Context>
</val:TotalQuantityValidator>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</UserControl>
В DataContext UserControl устанавливается экземпляр MyViewModel в коде. Я знаю, что это связывание работает как стандартные управляющие привязки, работают как ожидалось.
Метод TotalQuantityValidator.Validate
вызывается правильно, но всякий раз, когда я смотрю на свойство ViewModel
для Context
, он всегда равен нулю (свойство Context
объекта TotalQuantityValidator
устанавливается в экземпляр TotalQuantityValidatorContext
правильно). Однако я вижу из отладчика, что установщик в свойстве ViewModel
TotalQuantityValidatorContext
никогда не вызывается.
Может ли кто-нибудь посоветовать, как я могу заставить эту привязку работать?
Спасибо заранее.