Search code examples
wpfcustom-controlstemplatebinding

TemplateBinding in generic.xaml and repainting on Property changed


I've a custom control. In the custom controls, there are several elements. One of those element should have a special height value.

This height I'm talking about is CanvasThickness in the following code:

private double canvasThickness;

public static readonly DependencyProperty CanvasThicknessProperty =
  DependencyProperty.Register("CanvasThickness",
  typeof(double),
  typeof(CustomControl1),
  new FrameworkPropertyMetadata(3d));

public double CanvasThickness
{
  get { return canvasThickness; }
  set { canvasThickness = value; }
}

In generic.xaml is this CanvasThickness used for the Height-Property of a Canvas:

<ControlTemplate x:Key="SliderTemplate" TargetType="{x:Type Slider}">
  <Canvas Width="25" Height="{TemplateBinding local:CustomControl1.CanvasThickness}" Background="Green">
    // Templating Slider
  </Canvas>
</ControlTemplate>

<Style TargetType="{x:Type local:CustomControl1}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type local:CustomControl1}">
        <Canvas Width="50" Height="20" Background="GreenYellow">
          <Slider Template="{StaticResource SliderTemplate}" />
        </Canvas>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Now this Slider has a height of 3. Let's say I use the CustomControl like this:

<ctrl:CustomControl1 CanvasThickness="12"/>

I would assume, that the Slider would have a Height of 12. But it's still 3. The value of CanvasThickness is 12.

How do I repaint the CustomControl on PropertyChanged? I tried FrameworkPropertyMetadataOptions, but it does not affect the CustomControl.

Thanks in advance.

EDIT: If possible, the solution should also run in Silverlight.


Solution

  • The TemplateBinding in your Slider template is attempting to resolve a property called CanvasThickness on the templated control, which is a Slider, not your custom control.

    I don't understand the point of the Canvas in the first place. It's impossible to say without knowing exactly what you're trying to achieve, but I suspect you want something closer to this:

    <Style TargetType="{x:Type local:CustomControl1}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type local:CustomControl1}">
            <Border Width="50" Height="20" Background="GreenYellow">
              <Slider Template="{StaticResource SliderTemplate}" Height="{TemplateBinding CanvasThickness}" />
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
    

    Even then, the Border has hard-coded widths and heights which is generally a bad idea.