TemplateBinding inside ControlTemplate.Triggers

One of the limitations of TemplateBinding Markup in WPF is the fact that we cannot use it inside the ControlTemplate.Triggers because it really doesn’t work, since as Mike Hillberg said here, “TemplateBinding is a lightweight, but less functional, version of a Binding with a RelativeSource of TemplatedParent.  One of the things that a TemplateBinding can’t do is work within the ControlTemplate.Triggers; TemplateBinding only works within the template content” .

So we have this:

       MyControl.cs

  1: 	public class MyControl : Control
  2: 	{
  3: 
  4: 		public Boolean Selected
  5: 		{
  6: 			get { return (Boolean)GetValue(SelectedProperty); }
  7: 			set { SetValue(SelectedProperty, value); }
  8: 		}
  9: 
 10: 		// Using a DependencyProperty as the backing store for Selected.  This enables animation, styling, binding, etc...
 11: 		public static readonly DependencyProperty SelectedProperty =
 12: 			DependencyProperty.Register("Selected", typeof(Boolean), typeof(MyControl), new UIPropertyMetadata(false));
 13: 
 14: 
 15: 
 16: 		public Brush SelectedColor
 17: 		{
 18: 			get { return (Brush)GetValue(SelectedColorProperty); }
 19: 			set { SetValue(SelectedColorProperty, value); }
 20: 		}
 21: 
 22: 		// Using a DependencyProperty as the backing store for SelectedColor.  This enables animation, styling, binding, etc...
 23: 		public static readonly DependencyProperty SelectedColorProperty =
 24: 			DependencyProperty.Register("SelectedColor", typeof(Brush), typeof(MyControl), new UIPropertyMetadata(Brushes.Red));
 25: 
 26: 
 27: 		public MyControl()
 28: 		{			
 29: 		}
 30: 
 31: 		protected override void OnInitialized(EventArgs e)
 32: 		{
 33: 			base.OnInitialized(e);
 34: 
 35: 			this.MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(MyControl_MouseLeftButtonDown);
 36: 		}
 37: 
 38: 		void MyControl_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
 39: 		{
 40: 			MessageBox.Show(this.SelectedColor.ToString());
 41: 			this.Selected = !this.Selected;
 42: 		}
 43: 	}
 44: 


      Window1.xaml



  1: <Window x:Class="WpfApplication13.Window1"
  2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4: 	xmlns:local="clr-namespace:WpfApplication13"
  5:     Title="Window1" Height="300" Width="300">
  6:     <Grid>
  7: 		<local:MyControl x:Name="ctrl1">
  8: 			<local:MyControl.Template>
  9: 				<ControlTemplate TargetType="{x:Type local:MyControl}">
 10: 					<Grid Background="Green" x:Name="source"/>
 11: 					<ControlTemplate.Triggers>
 12: 						<Trigger Property="Selected" Value="true">
 13: 							<Setter TargetName="source" Property="Background" Value="{TemplateBinding SelectedColor}"/>
 14: 						</Trigger>
 15: 						<Trigger Property="Selected" Value="false">
 16: 							<Setter TargetName="source" Property="Background" Value="Green"/>
 17: 						</Trigger>
 18: 					</ControlTemplate.Triggers>
 19: 				</ControlTemplate>
 20: 			</local:MyControl.Template>
 21: 		</local:MyControl>
 22: 	</Grid>
 23: </Window>
 24: 


When we compile we get the following error, "Cannot convert the value in attribute ‘Value’ to object of type ”.  Error at object ‘System.Windows.Setter’ in markup file ‘WpfApplication13;component/window1.xaml’ Line 13 Position 58."



So how can we solve this problem?



   Since the problem here is that TemplateBinding is not supported inside the ControlTemplate.Triggers, we have to find another way to make the binding, and so we just change the line 13 to



  1: 							<Setter TargetName="source" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedColor}"/>


      And if we look at the TemplateBinding Markup page in MSDN, the usage of TemplateBinding is similar to the Binding Markup using TemplatedPart as the RelativeSource, like {Binding RelativeSource={RelativeSource TemplatedParent}, Path=DependencyPropertyToBind}



Hope this helps.

3 comments on “TemplateBinding inside ControlTemplate.Triggers

  1. Wookie on said:

    Thank you so much for posting this! This problem was driving me nuts.

  2. Sure it helped, thanks! :)

  3. Catalin on said:

    Really helpful, exactly what I was looking for!

Leave a Reply

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

*


*

* Copy This Password *

* Type Or Paste Password Here *

1,521 Spam Comments Blocked so far by Spam Free Wordpress

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>