Saturday 1 March 2014

How to create a Control Template for the Validation Error - WPF (XAML)

In this article we are going to see how to create a control template for the validation error, For this first we have to create a Validation error for a property and add the validation rule to the binding of the property with control. Then i will raise a validation error for that data binding and results in the change in the color for that control in the border, now we can change the template for that Validation Error, instead of making a border in red color , we going to see some cool stuff like adding additional things to the control by display the exclamatory symbol along with border red, 

For do this we have to create a control template and bind it with the validtion.ErrorTemplate which will override with the default template.

Control Template


AdornedElement Placeholder which represents the element used in the control template, to specify where the decorated element should be placed.

Now we have to create a DockPanel in which specify that the last element added in the collection can occupy the remaining space, so place the adorned element placeholder as last element and add a Border inside the Adorned Element placeholder which will give the color for the Template control on Error.

Control Template:

<ControlTemplate x:Key="errorTemplate">
            <DockPanel LastChildFill="True">
                <Border BorderBrush="OrangeRed" BorderThickness="1">
                <AdornedElementPlaceholder>                   
                    <Border HorizontalAlignment="Right"  BorderBrush="OrangeRed"  Width="20" Height="20" Margin="5" Background="OrangeRed" CornerRadius="5" DockPanel.Dock="Right">
                        <TextBlock Text="!"  VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontSize="20"></TextBlock>
                    </Border>                   
                </AdornedElementPlaceholder>
                </Border>
            </DockPanel>   
        </ControlTemplate>

        

After created the Template bind it with the Validation.ErrorTemplate


XAML :

<Window x:Class="AdornerSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ControlTemplate x:Key="errorTemplate">
            <DockPanel LastChildFill="True">
                <Border BorderBrush="OrangeRed" BorderThickness="1">
                <AdornedElementPlaceholder>                   
                    <Border HorizontalAlignment="Right"  BorderBrush="OrangeRed"  Width="20" Height="20" Margin="5" Background="OrangeRed" CornerRadius="5" DockPanel.Dock="Right">
                        <TextBlock Text="!"  VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontSize="20"></TextBlock>
                    </Border>                   
                </AdornedElementPlaceholder>
                </Border>
            </DockPanel>   
        </ControlTemplate>
       
        <Style x:Key="txt" TargetType="TextBlock">
            <Setter Property="HorizontalAlignment" Value="Right"></Setter>
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="FontSize" Value="14" />           
            <Setter Property="FontFamily" Value="Arial" />                
        </Style>
        <Style TargetType="TextBox" x:Key="mantxt">
            <Setter Property="Margin" Value="5"    />
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="Height" Value="50" />
            <Setter Property="Width" Value="250"/>
        </Style>
       
        <Style TargetType="TextBox" x:Key="katxt" BasedOn="{StaticResource mantxt}">
            <Setter Property="Foreground" Value="Green" />
        </Style>
       
        <Style x:Key="acc" TargetType="AccessText">
            <Setter Property="HorizontalAlignment" Value="Right"></Setter>
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="FontSize" Value="20" />
            <Setter Property="FontFamily" Value="Arial" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="2*" />          
        </Grid.ColumnDefinitions>
        <AccessText Grid.Row="0" Style="{StaticResource acc}" >Name</AccessText>
        <TextBox Style="{StaticResource mantxt}" Grid.Column="1" Validation.ErrorTemplate="{StaticResource errorTemplate}">
            <TextBox.Text>
                <Binding Path="Name">
                    <Binding.ValidationRules>
                        <ExceptionValidationRule />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <TextBlock Style="{StaticResource txt}" Grid.Row="1">Designation</TextBlock>
        <TextBox Text="{Binding Designation}"  Style="{StaticResource katxt}" Grid.Row="1" Grid.Column="1"></TextBox>
    </Grid>
</Window>



C#:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AdornerSample
{
    public class Employee
    {

        private string _name;
        public string Name
        {
            set { _name = value;
                if(string.IsNullOrEmpty(value))
                    throw new ApplicationException("Employee Name is Mandatory");
            }
            get { return _name; }
        }

        private int _id;
        public int Id {

            set
            {
                _id = value;
            }
            get {
                return _id;
            }
       
        }

        private string _designation;
        public String Designation
        {
            set { _designation = value; }
            get { return _designation; }
        }

        private int _salary;
        public int Salary {

            set { _salary = value; }
            get { return _salary; }
        }
    }
}



Output:




From this article anyone can easily understand how to create a control template in xaml.


1 comment: