A bit on TemplateBinding and how to use it inside a ControlTemplate.
Introductio
Today I'll try to write a bit on TemplateBinding
and how to use it inside a ControlTemplate
.TemplateBinding
is a type of binding used mainly for template scenarios. Here I am not going to write more on its theoretical aspect as what is TemplateBinding
, when to use, blah blah blah, as lot of content is readily available on the net. So, let's start quickly with the coding part:
First of all, let's create a new project using WPF template and place a button in it as below:
Now, what I am going to do is, I am going to replace this content template for this button. So, in order to do this, open up the Button tag and add Button.Template
markup tag with a new ControlTemplate
as:
Now as soon as you will add ControlTemplate
tag, you will notice that the content of the button is gone and button is shown as a transparent rectangle. This has happened because here I told WPF to replace the defaultControlTemplate
with the one which I defined. But at this point, our ControlTemplate
is blank, so there is no visualization and we can see only a transparent rectangle.
Now go ahead and customize our ControlTemplate
by putting Ellipse
inside it as:
Now we can see that we get a visualization for a button in the form of ellipse. At this point of time, it works OK, but there are scenarios where this struct
breaks down.
For example, let's increase the height of button
, from 35
to 105
as:
In the above image, you will notice that button height is increased but the ellipse size is still the same, which is a bad UI design. And the reason this is happening is, inside a ControlTemplate
, the height of an ellipse is hard coded. So, no matter, whatever height is set at parent (i.e., Button
), it will not get inherited to child control (i.e.Ellipse
).
So, now we have to fix this problem by using a special type of binding called TemplateBinding
insideControlTemplate
. So, instead of hard coding the height, we will use TemplateBinding
as shown below:
By setting the TargetType
property of ControlTemplate
, we are telling Ellipse
that, any property of Button
can be set to ellipse
. Now, whatever the height of button will be, it will automatically be the height of ellipse
also. Isn't it interesting?
Moving forward, let's do something more interesting with Fill
property of ellipse
.
In the above snippet, I am trying to set the Fill
property of an ellipse
using TemplateBinding
. But now the problem here is, a button
doesn't have a Fill
property. So, there is no one-to-one mapping for Fill
property. Now, what to do?
No need to worry that much because button
does have a Background
property as:
In the above image, you might have noticed that as soon as ellipse
's Fill
property is set to Background
,ellipse
becomes transparent as button
's background. Now if we set button
's Background
property to Red
, the same will be applied to ellipse
too.
So, one can understand how much magic we can do with TemplateBinding
.
Now, let's work a little bit on code cleanup.
ControlTemplate Inside Resource Dictionary
For better code readability, we will move out our ControlTemplate
code and put it inside a resource dictionary as:
So, now we can see as earlier that whatever visual property for button
is set, all get applied to ellipse
as well.
Hope this tip was useful and gave you the basic idea on how to use TemplateBinding
.