Wednesday, April 6, 2011

Extend the functionality of WPF Control using Custom Control


Here, we will learn how to extend the functionality of existing WPF control. This will help you in that situation when you want to create a control with new style and design but don’t want to write basic properties of that control like “IsSelected”, “SelectedItem” for TabControl  and “Content” of Button etc.
To achieve this, you have to follow these steps and finally you'll get your own Custom Control with new “Name” and “Style” which inherits all the basic properties of that WPF Control.
Note: You can extend any WPF Control with these steps, but here I am taking a simple example of “Button” Control for better and quick explanation.
I am hoping that, you know what is Custom Control? And how we create simple Custom Control using Dependency and Attached Properties?

1. First add “Custom Control” and name it “ButtonExtendControl.cs”.



 

 

 

 

 
 
 




2. When we open “ButtonExtendControl.cs” file, we'll find the class inherited with “Control” which is a base class for all WPF Controls.
public class ButtonExtendControl : Control

Now what we will do, instead of inheriting with “Control” inherit it with that Control from which we want to extend our Custom Control (like Button, Combobox, TabControl, Checkbox, etc.). Here we are extending our Custom Control with “Button” that’s why we inherited it with “Button” class like this:
       public class ButtonExtendControl : Button

3. Now extract the Style and Template using expression blend of that control from which we want to extend our Custom Control. Here we extract the Style and Template of “Button” like this:
Steps: Right click on Button Control --- Edit Template --- Edit a Copy


 

 

 

 

 

 

 
 

You'll get the “Style” with all “Setters” and “Templates” in the code behind page of expression blend.

4. Now copy contains of “ControlTemplate” and paste into the “ControlTemplate” of ButtonExtendControl style which is in “Generic.xaml”. Do the same for all setter properties and paste into the style like this


5. Now when we call “ButtonExtendControl” in “MainWindow.xaml” using below code, it looks like same as WPF Button. Because we just copy paste the Style and Template in our new custom control, we didn’t make changes it the style or template.

local:ButtonExtendControl Content="Custom Button" Width="200" Height="40"

6. Now we edit the “ControlTemplate” and add one Dependency Property (“ButtonCornerRadius”) in our Custom Control ("ButtonExtendControl").
To edit ControlTemplate we'll replace the tag Microsoft_Windows_Themes:ButtonChrome with the “Border” like this:
Here we are setting one dependency property (which is an additional functionality for the "Button" Control), so that user can set the corner radius according to their desire and change the shape of button like rectangle, rounded, oval or circle.
CornerRadius="{Binding ButtonCornerRadius, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
 
In “ButtonExtendControl.cs” we write this code for dependency property, default value for this dependency property is zero.
public double ButtonCornerRadius
 {
  get { return (double)GetValue(ButtonCornerRadiusProperty); }
  set { SetValue(ButtonCornerRadiusProperty, value); }
 }

public static readonly DependencyProperty ButtonCornerRadiusProperty =
      DependencyProperty.Register("ButtonCornerRadius", typeof(double),
      typeof(ButtonCustomControl), new UIPropertyMetadata(0.0));



 
Note: Most important thing is how to set dependency property.
 
If we'll use “TemplateBinding” or “Binding” keyword for CornerRadius, It'll not work because we are extending our custom control with another control.

Thats why, we use RelativeSource so that we enforce the binding to take value of ButtonCornerRadius from ButtonExtendControl class which is basically of Button type.
CornerRadius="{Binding ButtonCornerRadius, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"











Now see how the developer can change the shape of this Custom Control by just changing the value of ButtonCornerRadius property.

Rectangle Shape
local:ButtonExtendControl Content="Custom Button" Width="200" Height="40" ButtonCornerRadius="0"








Rounded Shape
local:ButtonExtendControl Content="Custom Button" Width="200" Height="40" ButtonCornerRadius="20"







Circle Shape
local
:ButtonExtendControl Content="Custom Button" Width="100" Height="100" ButtonCornerRadius="50"










Here is the code sample for better understanding.

Thanks
Hope this will help you.

No comments:

Post a Comment