У меня есть пользовательский ValidationRule, который требует доступа к ViewModel, чтобы проверить поставляемое значение в сочетании с другими свойствами ViewModel. Я ранее пытался добиться этого, используя ValidationGroup, но отказался от этой идеи, поскольку код, который я изменяю, потребует много рефакторинга, чтобы включить этот маршрут.Binding DataContext to ValidationRule
Я нашел thread on a newsgroup, который показал способ привязки DataContext элемента управления, в котором ValidationRule выполняется для этого ValidationRule посредством промежуточного класса, унаследованного от DependencyObject, но я не могу его привязать.
Может ли кто-нибудь помочь?
Мой 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
никогда не вызывается.
Может ли кто-нибудь посоветовать, как я могу заставить это обязательство работать?
Заранее спасибо.
Я знаю, что этот вопрос похож на http://stackoverflow.com/questions/3577899/wpf-property-in-validationrule-never-set, но я ищу доступ к DataContext, а не только к другому свойству. – 2010-12-03 13:05:29