TemplateBinding does not work in certain cases(when using TranslateTransform)
Asked Answered
P

2

7

This is how I reproduced this problem in WPF:

Create a custom control:

public class TestCustomControl : Control
{
static TestCustomControl()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(TestCustomControl), new FrameworkPropertyMetadata(typeof(TestCustomControl)));
}

public string Text
{
    get { return (string)GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
}

// Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text", typeof(string), typeof(TestCustomControl), new PropertyMetadata("Hello"));

public double OffSet
{
    get { return (double)GetValue(OffSetProperty); }
    set { SetValue(OffSetProperty, value); }
}

// Using a DependencyProperty as the backing store for OffSet.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty OffSetProperty =
    DependencyProperty.Register("OffSet", typeof(double), typeof(TestCustomControl), new PropertyMetadata(5.0));
}

Add a style for it in the Generic.xaml file:

<Style TargetType="local:TestCustomControl">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="local:TestCustomControl">
            <Grid>
                <TextBlock Text="{TemplateBinding Text}"></TextBlock>
                <TextBlock Text="{TemplateBinding Text}">
                    <TextBlock.RenderTransform>
                        <TranslateTransform X="{TemplateBinding OffSet}" Y="{TemplateBinding OffSet}"/>
                        <!--<TranslateTransform X="10" Y="10"/>-->
                    </TextBlock.RenderTransform>
                </TextBlock>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>

Then add it to the main window:

<local:TestCustomControl OffSet="32" Text="the off set is not working" FontSize="36">

    </local:TestCustomControl>

Then run the application, it turned out the "Text" works fine but the "OffSet" does not work. And I tried the similar thing in Windows Phone 7 development environment, and I got the same result.

How should I modify the code to make the OffSet work?

Thanks

Piscary answered 14/6, 2011 at 16:8 Comment(1)
According to "WPF 4.5 Unleashed," Nathan, Adam; 3rd ed. c. 2014, p. 437, you can't use TemplateBinding on the properties of a Freezeable. TranslateTransform is a Freezeable, so that's why it didn't work (whereas TextBlock is not a Freezeable, so that is why it did work there). What's puzzling is that this is not a run-time (or any-other-time) error. It just fails silenty.Bullard
N
21

Try:

{Binding Offset, RelativeSource={RelativeSource TemplatedParent}}
Nippers answered 14/6, 2011 at 16:10 Comment(5)
just tested again, it does not work for Silverlight3, works for Silverlight4.Corabelle
WP7.0 has a rather dilute "Silverlight 4". The Silverlight4 implementation shipped with WP7.1 (aka Mango) is much more complete and CuiPengFei's solution will probably start working.Emergent
I'm now running Mango and Kent's solution (the full relative source syntax) does indeed work under Mango. Which is just as well, because now the TemplateBinding syntax produces an "unspecified exception" inside the framework. If I may, I suggest also including Mode=OneWay because this makes it semantically identical to TemplateBinding, not to mention more efficient.Emergent
I was having issues with TemplateBinding. Changing it to the long form helped me figure out what was wrong. Thanks!Carolynncarolynne
I wish I could understand that kind of sorcery.Thorner
P
1

Both of TemplateBing and RelativeSource do not work, so just forget about it if you are targeting WP7.0 (Silverlight 3). Use some other ways to work it around. I actually manually changed the X/Y values of each transform every time the "OffSet" is changed.

Piscary answered 17/6, 2011 at 4:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.