tags:

views:

201

answers:

1

I have a button that I want to bind the scaleX and scaleY to the scaleX and scaleY of another element, how can I do that?

The tricky part is that I want to bind it to an element that, at least on initialisation, may not have a ScaleTransform set on it...

+3  A: 

Ideally, set it up so that the bindee element does always have a ScaleTransform, but it's the identity transform. Then name that ScaleTransform, and bind to it using the usual element-to-element syntax:

<TextBlock Text="One">
  <TextBlock.LayoutTransform>
    <ScaleTransform ScaleX="1"
                    ScaleY="1"
                    x:Name="s" />  <!-- Note the x:Name -->
  </TextBlock.LayoutTransform>
</TextBlock>

<TextBlock Text="Two">
  <TextBlock.LayoutTransform>
    <ScaleTransform ScaleX="{Binding ScaleX, ElementName=s}"
                    ScaleY="{Binding ScaleY, ElementName=s}" />
  </TextBlock.LayoutTransform>
</TextBlock>

If you need to bind to the element specifically, you can traverse down through the properties e.g. {Binding LayoutTransform.ScaleX, ElementName=someElement}. This will no-op if the source element has no LayoutTransform or it isn't a ScaleTransform, but it will report runtime binding errors.

itowlson
ok, thanks! So to make matters a bit more complicated, I need to bind to the textblocks template parent... so I need to use templateBinding, is still valid for this situation?
Mark
I think so, but you may need to use `{RelativeSource TemplatedParent}` rather than `{TemplateBinding}`, and I'm pretty sure you will need to use the LayoutTransform.ScaleX approach rather than the ElementName approach (since you can't have both a RelativeSource and an ElementName). Thus, `{Binding LayoutTransform.ScaleX, RelativeSource={RelativeSource TemplatedParent}}`. By the way, something to consider: do you specifically want to bind a scale, or just the entire transform e.g. `TextBlock LayoutTransform="{TemplateBinding LayoutTransform}"`?
itowlson
good question, I think scale should be enough... ill let you know though. I did try what you have just suggested, but I get the binding error: path error: 'ScaleX' property not found on 'object' 'MatrixTransform'. So I changed my bind expression to be: <MatrixTransform Matrix="{Binding LayoutTransform.ScaleX, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBloxk}}}" /> But this did not do anything or give errors :(
Mark
BTW, how exactly do you highlight a code snippet in a comment?
Mark
To highlight a code snippet in a comment, use a backtick aka backquote (on my keyboard, it's to the left of the "1" key, but this may depend where you live!).
itowlson
LayoutTransform.ScaleX will work only if the LayoutTransform of the source really is a ScaleTransform. If it's unspecified, or is a TransformGroup or anything else, then you're out of luck. In this case, you may need to instead define your own custom property/ies on the control being templated, named to make it clear what about the control being scaled, e.g. ContentScaleX and ContentScaleY. (If you're templating an existing control, you can use attached properties for this.)
itowlson
Awesome, thanks for the help!
Mark