Note that there are some explanatory texts on larger screens.

plurals
  1. POBinding DataContext to ValidationRule
    primarykey
    data
    text
    <p>I have a custom ValidationRule that requires access to the ViewModel in order to validate a supplied value in conjunction with other properties of the ViewModel. I previously tried to acheive this by using a ValidationGroup, but abandoned this idea as the code I am modifying would need a lot of refactoring in order to enable this route.</p> <p>I found a <a href="http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/982e2fcf-780f-4f1c-9730-cedcd4e24320/" rel="noreferrer">thread on a newsgroup</a> that showed a way of binding the DataContext of a control in which the ValidationRule is being run to that ValidationRule by way of an intermediate class inherited from DependencyObject, but I cannot get it to bind.</p> <p>Can anybody help?</p> <p>My ValidationRule is as follows...</p> <pre><code>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 &amp;&amp; this.Context.ViewModel != null) { int total = ... if (total &lt;= 0 || total &gt; 255) { validationResult = new ValidationResult(false, this.ErrorMessage); } } return validationResult; } } </code></pre> <p>CustomValidationRule is defined as follows...</p> <pre><code>public abstract class CustomValidationRule : ValidationRule { protected CustomValidationRule(string defaultErrorMessage) { this.ErrorMessage = defaultErrorMessage; } public string ErrorMessage { get; set; } } </code></pre> <p>TotalQuantityValidatorContext is defined as follows...</p> <pre><code>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) { } } </code></pre> <p>And the whole thing is used thus...</p> <pre><code>&lt;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"&gt; &lt;TextBox Name="myTextBox"&gt; &lt;TextBox.Text&gt; &lt;Binding NotifyOnValidationError="True" Path="myViewModelProperty" UpdateSourceTrigger="PropertyChanged"&gt; &lt;Binding.ValidationRules&gt; &lt;val:TotalQuantityValidator&gt; &lt;val:TotalQuantityValidator.Context&gt; &lt;val:TotalQuantityValidatorContext ViewModel="{Binding ElementName=myUserControl, Path=DataContext}" /&gt; &lt;/val:TotalQuantityValidator.Context&gt; &lt;/val:TotalQuantityValidator&gt; &lt;/Binding.ValidationRules&gt; &lt;/Binding&gt; &lt;/TextBox.Text&gt; &lt;/TextBox&gt; &lt;/UserControl&gt; </code></pre> <p>The DataContext of the UserControl is being set to an instance of MyViewModel in code-behind. I know that this binding works as the standard control bindings are operating as expected.</p> <p>The <code>TotalQuantityValidator.Validate</code> method is called correctly, but whenever I look at the <code>ViewModel</code> property of the <code>Context</code>, it is always null (the <code>Context</code> property of the <code>TotalQuantityValidator</code> is being set to an instance of <code>TotalQuantityValidatorContext</code> correctly). I can see from the debugger however that the setter on the <code>ViewModel</code> property of the <code>TotalQuantityValidatorContext</code> is never called.</p> <p>Can anybody advise as to how I can get this binding to work?</p> <p>Thanks in advance.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload