tags:

views:

3949

answers:

7

I am trying to use Validation in WPF. I created a NotNullOrEmptyValidationRule as shown below:

public class NotNullOrEmptyValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            if (String.IsNullOrEmpty(value as String))
                return new ValidationResult(false, "Value cannot be null or empty");

            return new ValidationResult(true, null); 
        }
    }

Now, I need to use it in my application. In my App.xaml file I declared the Style for the TextBox. Here is the declaration.

 <Style x:Key="textBoxStyle" TargetType="{x:Type TextBox}">

            <Setter Property="Background" Value="Green"/>

            <Style.Triggers>

                <Trigger Property="Validation.HasError" Value="True">

                    <Setter Property="Background" Value="Red"/>
                    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors)[0].ErrorContent}"/>

                </Trigger>

            </Style.Triggers>

        </Style>

Now, I want to use it on my TextBox so I am using the following code:

  <TextBox Style="{StaticResource textBoxStyle}">
                <TextBox.Text>
                    <Binding>
                        <Binding.ValidationRules>
                            <NotNullOrEmptyValidationRule />
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>


            </TextBox>

The error comes on the Tag NotNullOrEmptyValidationRule. The XAML syntax checker is not able to resolve the NotNullOrEmptyValidationRule. I have even tried putting the namespace but it does not seem to work.

A: 

There is a bug in Visual Studio and Expression Blend that causes this problem. What you need to do is make sure that the Validation rule is in a separately project/assembly that you can reference. This should resolve the problem.

However, you will have to add back the namespace in order for it to work.

Orion Adrian
A: 

I moved it into a separate library bit still it does not work:

<Binding.ValidationRules>
                            <WPFClassLibrary.NotNullOrEmptyValidationRule/>
                        </Binding.ValidationRules>

and even the following does not work:

<Binding.ValidationRules>
                            <WPFClassLibrary:NotNullOrEmptyValidationRule/>
                        </Binding.ValidationRules>
azamsharp
+4  A: 

You just need to add the xmlns to your Window, and use that to reference your ValidationRule.

In WPF, the object is perfectly fine to be used from the same assembly.

Since your rule isn't defined in the standard XAML namespace, you have to create a mapping to your clr namespace like so:

<Window ...
    xmlns:local="clr-namespace:MyNamespaceName">

And then you would use it like so:

<Binding Path=".">
    <Binding.ValidationRules>
        <local:NotNullOrEmptyValidationRule />
    </Binding.ValidationRules>
</Binding>

Edit I added a Path statement to the Binding. You have to tell the Binding what to bind to :)

Abe Heidebrecht
A: 

@Abe Heidebrecht,

Thanks! that error is now gone but now I have a different error. The error comes on the following line:

  <TextBox Style="{StaticResource textBoxStyle}">
                <TextBox.Text>
                    <Binding>
                        <Binding.ValidationRules>
                            <local:NotNullOrEmptyValidationRule/>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>

And the error is:

System.Windows.Markup.XamlParseException was unhandled Message: 'System.Windows.Data.Binding' value cannot be assigned to property 'Text' of object 'System.Windows.Controls.TextBox'. Two-way binding requires Path or XPath. Error at object 'System.Windows.Data.Binding' in markup file 'WFPApplication;component/window1.xaml' Line 20 Position 23.

Any ideas!

azamsharp
You have to specify what the Binding is binding to. So, you have to set the Path property. If you are binding to the current DataContext, you can set it to "."
Abe Heidebrecht
Thanks Abe, I'm reviving an ancient thread to +1 your tip "If you are binding to the current DataContext, you can set it to "."" I searched all over the net to find that tidbit!
bufferz
A: 

Hi Abe Heidebrecht,

Here is my updated code.

 <TextBox Style="{StaticResource textBoxStyle}">  

                <TextBox.Text>

                    <Binding Path="Text" UpdateSourceTrigger="LostFocus">

                        <Binding.ValidationRules>
                            <local:NotNullOrEmptyValidationRule/>
                        </Binding.ValidationRules>

                    </Binding>

                </TextBox.Text>


            </TextBox>

Still is it not firing the validations. It should make the textbox background red. Here the the NotNullOrEmptyValidationRule class.

public class NotNullOrEmptyValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { if (String.IsNullOrEmpty(value as String)) return new ValidationResult(false, "Value cannot be null or empty");

    return new ValidationResult(true, null); 
}

}

azamsharp
+1  A: 

i see your binding on the TextBox is set to a path of 'Text' - is that a field on whatever the datacontext of this textbox is? is the textbox actually getting a value put into it? also, if you put a breakpoint in your validation method, is that ever getting fired?

you may want to lookup how to log failures in binding and review those as well..

SmartyP
A: 

You do not have this line in ur code behind

Public Sub New()

    ' This call is required by the Windows Form Designer.
    InitializeComponent()

    Me.**NameOfTextBox**.DataContext = Me
End Sub
lmheah