TemplateBinding and TemplateParent Digging

9 בMay 2016

אין תגובות

One of the things that can completely freak you out.
Lets start with facts:

1.  While customize an application you might use something like this:

<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=MyProperty}"/>

Or maybe this:

<TextBlock Text="{TemplateBinding MyProperty}" />

While this is on the ResourceDictionary of your app and about to styling your custom control, and MyProperty is an DependencyProperty on the logic part of the Control

so what the different between those two?  And what the default choose should be?
By the way while most of programmers used to write
You can use the Short way as:

Text=”{Binding TemplatedParent.MyProperty2}”

2.    A full demonstration will be like  this one:

public class CustomControl1 : Control

    {

        static CustomControl1()

        {

            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));

        }


        public CustomControl1()

        {

            MyProperty = 99;

        }


        public int MyProperty

        {

            get { return (int)GetValue(MyPropertyProperty); }

            set { SetValue(MyPropertyProperty, value); }

        }


        public static readonly DependencyProperty MyPropertyProperty =

            DependencyProperty.Register("MyProperty", typeof(int), typeof(CustomControl1), new PropertyMetadata(0));

    }

And the Xaml part:

<Style TargetType="{x:Type local:CustomControl1}">

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="{x:Type local:CustomControl1}">

                    <StackPanel>

                        <TextBlock Text="{TemplateBinding MyProperty}" />

                        <TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=MyProperty}" />

                    </StackPanel>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

On purpose I used they both in my demo .
while running this code you will probably be aware that  TemplateBinding  doesn’t appear on your screen. Is it true?
3.
what is it  TemplateParent?(By MSDN documentation) TemplatedParent refers to the Control instance that the template is being applied to
Meaning when you using ControlTmplate this is the connection from the Xaml side to the Control source.
And what is TemplateBinding?  (By MSDN documentation)
TemplateBinding is used for binding to the element properties within the template definition
Confusing ??
Wait for this , go to your control and Change the MyProperty Definition type to String, now it works!!
Confusing ??
Wait for this, go back to your Code and restore MyProperty to Int,  than dd a Converter, name it as you wish and do nothing inside it,
I mean do something like:

public class DoNothingConverter : IValueConverter

    {

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            return value;

        }


        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            throw new NotImplementedException();

        }

    }

It may looks as stupid thing to do, and no disagreement, but please give it a try,
Than connect it to your control Theme library.

<local:DoNothingConverter x:Key="converter" />



    <Style TargetType="{x:Type local:CustomControl1}">

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="{x:Type local:CustomControl1}">

                    <StackPanel>

                        <TextBlock Text="{TemplateBinding MyProperty , Converter={StaticResource converter}}" Foreground="Black"/>

                        <TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=MyProperty}" Foreground="Red" />

  </StackPanel>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

well well.. Now, when we sure that there is a problem lets think..
4.
It seems that they both do kind of same except that the internal converter of TemplateBinding is missing functionality of ToString .
While every FrameworkElement has a TemplatedParent which is deeply embedded in the Xaml Parser structural, and use it for regular Binding
TemplateBinding is just an  Extension of MarkupExtension where designed to regard to original element property when creating a template for Control, so default built in values has the proper converters, but with personal binding targeting like in custom controls you must provide the converter.
Also It is totally wrong to say that TemplateBinding is shortcut for TemplateParent as I found around the web.
(from MSDN)
You use TemplateBinding in template to bind to a value on the control the template is applied to. A TemplateBinding is more efficient than a Binding but it has less functionality. Using a TemplateBinding is equivalent to using a Binding with the RelativeSource property set to RelativeSource.TemplatedParent.

הוסף תגובה
facebook linkedin twitter email

Leave a Reply

Your email address will not be published. Required fields are marked *