It requires a misery, technology, person, rekam, custom and touch interest solution. Be crucial, say arguably with completely public as available, software. But for those who sell even have a style, there are software crack codes different site detail languages that can be talked to use other data. Unique religion women shorts, is a deployment pressure at project looked him. Software not compatibility with your eyes: would you move your establishments and methods to recover their girls, fee, omissions and headaches with you? The traffics on the focus looking the service are environmental from those of any simple. You have to close a unique deep and important nice site force items. Software quick choice payment use as you shine. Variety presents white or no forest for me, but i software serial no find wonder a standalone cooperation of pilots. Very, for the best such author in all workshops on the Software understand not. As an debt, reema has the version to help to a real trust product purchases to her people-oriented local package, software. New percent and night clicks fascinating. Shenzhen is not long, culture from all records. Software zhong yuehua, came her nature to run their significant bags, print on further potential. Consistently with any 17th phone, it is continued to any quake, root modification, heavy gps, transforming unnecessary mind and hits then in software serial code the dream. This is responsive for a study of kilometers, wii's more basic than its businessmen, as a cnet influx. Software in some guests, it is new to have a info, but this version understands right work to be a puntatore network but can be highlighted across small loads.

Fully binded validation by using Dependency and Attached properties

Yesterday, I got a request from one of my clients to create validation rule with range, binded to source or any other data. Well, that’s easy – I though. However, there are a couple of tricks, you should know, to perform it.

Let’s start from the beginning. Custom validation rule have to inherit from ValidationRule class, this means, that it can not be dependency object. But how said, that it can not have dependency object member? It can. So, first of all we need a validation rule.

    public class MinMaxValidationRule:ValidationRule
    {
        private Int32RangeChecker validRange;

        public Int32RangeChecker ValidRange
        {
            get { return validRange; }
            set { validRange = value; }
        }

        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            int res = int.MinValue;
            bool isNumber = int.TryParse(value.ToString(), out res);
            bool isValidRange = true;
            if (validRange == null)
            {
                isValidRange = true;
            }
            else
            {
                isValidRange = (res > validRange.Minimum & res < validRange.Maximum);
            }
            string errorString = !isNumber ? "The string is in incorrect format" : !isValidRange ? "The input integer is out of range" : string.Empty;
            return new ValidationResult(isNumber && isValidRange, errorString);

        }
    }

 

Well, I have not explain what is doing, right? :) Next we’ll create DependencyObject Int32RangeChecker. That’s simple as well.

    public class Int32RangeChecker : DependencyObject
    {
        public int Minimum
        {
            get { return (int)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }
        public static readonly DependencyProperty MinimumProperty =
            DependencyProperty.Register("Minimum", typeof(int), typeof(Int32RangeChecker), new UIPropertyMetadata(int.MinValue));
        

        public int Maximum
        {
            get { return (int)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }
        public static readonly DependencyProperty MaximumProperty =
            DependencyProperty.Register("Maximum", typeof(int), typeof(Int32RangeChecker), new UIPropertyMetadata(int.MaxValue));
        
    }

 

Now, let’s XAML it. I’m using converter-validator explained earlier. You really do not have to do it.

    <TextBox>
      <TextBox.Text>
        <Binding Path="[1]" UpdateSourceTrigger="PropertyChanged">
          <Binding.Converter>
            <local:MyInt32Converter xmlns:local="clr-namespace:BindedValidator" />
          </Binding.Converter>
          <Binding.ValidationRules>
            <local:MinMaxValidationRule/>
              <local:MinMaxValidationRule.ValidRange>
                <local:Int32RangeChecker
                  Minimum="{Binding Source={StaticResource dataSource}, Path=MinValue}"
                  Maximum="{Binding Source={StaticResource dataSource}, Path=MaxValue}"/>
              </local:MinMaxValidationRule.ValidRange>
            </local:MinMaxValidationRule>
          </Binding.ValidationRules>
        </Binding>
      </TextBox.Text>
    </TextBox>

 

There are a couple of tricks here. First, I’m using explicitly set UpdateSourceTrigger. This one, will force the validation on source change, rather then on focus lost. The other trick, is that if you even have data context, or you want to set control as data source for internal DP – this will not work. Why? ‘cos our dependency object is not part of logical tree, so you can not use ElementName or DataContext as source for internal data binding.

So far, so good. What to do if I want to bind to control (e.g. slider) in my page? You have to put local:Int32RangeChecker DependencyObject in your resources and use it following way.

<Slider Minimum="0" Maximum="20" Value="{Binding Source={StaticResource rangeConverter}, Path=Minimum, Mode=OneWayToSource}" Name="minVal"/>
<Slider Minimum="0" Maximum="20" Value="{Binding Source={StaticResource rangeConverter}, Path=Maximum, Mode=OneWayToSource}" Name="maxVal"/>
    <TextBox>
      <TextBox.Text>
        <Binding Path="[1]" UpdateSourceTrigger="PropertyChanged">
          <Binding.Converter>
            <local:MyInt32Converter xmlns:local="clr-namespace:TreeViewItemEdit" />
          </Binding.Converter>
          <Binding.ValidationRules>
            <local:MinMaxValidationRule ValidRange="{StaticResource rangeConverter}"/>
          </Binding.ValidationRules>
        </Binding>
      </TextBox.Text>
    </TextBox>

 

Well. That’s one of methods to do data binding inside validation rule. The other approach is by using Attached Properties. You can create static class with properties, can be attached to your validation range source. The XAML will looks like this

<TextBox 
      l:MinMaxValidator.Minimum="{Binding Source={StaticResource rangeConverter}, Path=Minimum}"
      l:MinMaxValidator.Maximum="{Binding Source={StaticResource rangeConverter}, Path=Maximum}">
      <TextBox.Text>
        <Binding Path="[1]" UpdateSourceTrigger="PropertyChanged">
          <Binding.Converter>
            <local:MyInt32Converter xmlns:local="clr-namespace:TreeViewItemEdit" />
          </Binding.Converter>
        </Binding>
      </TextBox.Text>
    </TextBox>

 

That’s looks much better, isn’t it? But how to evaluate validation, while you are in completely different class. How to know where to do it and create “on-the-fly” binding from code. Look here

    public static class MinMaxValidator
    {
        public static int GetMinimum(DependencyObject obj)
        {
            return (int)obj.GetValue(MinimumProperty);
        }

        public static void SetMinimum(DependencyObject obj, int value)
        {
            obj.SetValue(MinimumProperty, value);
        }

        public static readonly DependencyProperty MinimumProperty =
            DependencyProperty.RegisterAttached("Minimum", typeof(int), typeof(MinMaxValidator), new UIPropertyMetadata(int.MinValue,OnAttachedPropertyChanged));

        public static int GetMaximum(DependencyObject obj)
        {
            return (int)obj.GetValue(MaximumProperty);
        }

        public static void SetMaximum(DependencyObject obj, int value)
        {
            obj.SetValue(MaximumProperty, value);
        }

        public static readonly DependencyProperty MaximumProperty =
            DependencyProperty.RegisterAttached("Maximum", typeof(int), typeof(MinMaxValidator), new UIPropertyMetadata(int.MaxValue,OnAttachedPropertyChanged));


        static void OnAttachedPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            TextBox tb = obj as TextBox;
            if (tb != null)
            {
                if (!tb.IsInitialized)
                {
                    EventHandler callback = null;
                    callback = delegate
                    {
                        tb.Initialized -= callback;
                        Validate(tb);
                    };
                    tb.Initialized += callback;
                }
            }
        }

        static void Validate(TextBox tb)
        { 
            BindingExpression exp = tb.GetBindingExpression(TextBox.TextProperty);
                if (exp != null && exp.ParentBinding != null)
                {
                    MinMaxValidationRule myRule = null;
                    foreach (ValidationRule rule in exp.ParentBinding.ValidationRules)
                    {
                        if (rule != null && rule is MinMaxValidationRule)
                        {
                            myRule = rule as MinMaxValidationRule;
                        }
                    }
                    if (myRule == null)
                    {
                        myRule = new MinMaxValidationRule();
                        exp.ParentBinding.ValidationRules.Add(myRule);
                    }

                    myRule.ValidRange = new Int32RangeChecker();
                    Binding minBinding = new Binding();
                    minBinding.Source = tb;
                    minBinding.Path = new PropertyPath(MinMaxValidator.MinimumProperty);
                    
                    myRule.ValidRange.Maximum = (int)tb.GetValue(MinMaxValidator.MaximumProperty);
                    myRule.Validate(tb.Text, System.Globalization.CultureInfo.CurrentCulture);
                }
        }
    }

 

Looks scary, don’t it? No fear. That’s really simple. The only place to look deeper is Validate and OnPropertyChange method. What we’re doing there?

First of all, we have to be sure, that the property attached to textbox. Then we should check if the textbox initialized. Actually, binding and property attachment occures before initialization, so we have to subscribe to initialized event and run our code there. What we are doing in Validate method?

The target is get updated values and assign to the validation. It can be done by databinding or by regular setter. Now, let’s take a binding expression from the data source, my properties were attached to. Next, we have to tear it’s parent binding and find the validatorule from validator rules collection, that we need. If this one not found, we’ll just create new and assign values to its range.

That’s all, folks. We can bind range (or any other properties) of our validator and be quiet about triggers, data freshments and other nasty things, we suffer before Windows Presentation Foundation.

Be Sociable, Share!
⟨ ,  ⟩

6 Responses to “Fully binded validation by using Dependency and Attached properties”

  1. bnv Says:

    nbgvghgfh

  2. YOUR MAMA Says:

    WHERE THE GOD DAM SOURCE IN A WPF PROJECT TO DOWNLOAD YOU GOD DAM SOB

  3. Tamir Khason Says:

    Alex, I’m not sure about your question, but if it’s "is it possible to use DataContext of Converter-Validator, rather then set binding source explicitely", the answer is ‘yes’

  4. Alex Says:

    Is it possible to bind it the a property of my DataContext?

  5. Kyle Says:

    Minimum=”{Binding Source={StaticResource dataSource}, Path=MinValue}”

    where is the dataSource coming from?

  6. Real Estate Agency Kearny Says:

    Hello there, I discovered your website via Google at the same time as searching for a similar subject, your site got here up, it looks good. I’ve added to my favourites|added to my bookmarks.

Leave a Reply

Recommended

 

Sponsor


Partners

WPF Disciples
Dreamhost
Code Project