views:

6478

answers:

6
+1  Q: 

WPF Style Trigger

I change the FontSize of Text in a Style trigger, this causes the Control containing the text to resize as well. How can I change the Fontsize without affecting the parent's size?

A: 

What kind of control are you using? If this is a HeaderedControl like a GroupBox or TabItem then you need to specifically set the HeaderTemplate like this:

<DataTemplate x:Key="MyHeaderTemplate">
  <TextBlock Text="{Binding}" Fontsize="14" FontWeight="Bold" />
</DataTemplate>
Micah
A: 

I can think of a couple of things you could try:

  • You can override the Measure Pass of the control - when a control is rendered in WPF it undergoes two passes. The first is a 'measure pass', where the control comes up with what sizes that it wants to be. The second is the 'arrange pass', where it actually lays out the control. WPF provides a method called MeasureOverride. If you override this method you can provide custom behavior that can be used to adjust the size of the control.

    Note - I believe that you will have to call the Measure method all of your controls children during this override in order to get your control to lay out properly.

  • Hard code the height and width on the control - this will override the control's DesiredSize with your values. While generally a not the greatest of ideas, it will work.

NigelTufnel
A: 

I am creating a ControlTemplate for a ButtonControl so it looks like a label (flat text, no borders) with triggers for IsKeyboardFocused, IsPressed, IsDefaulted etc.

The IsPressed is defined to drop the FontSize (from default of 30) down to 28. To give a pressed animation effect.

One use of these Buttons is a horizontal StackPanel of Button, separated by vertical separators. When the IsPressed trigger is fired on a button and it is resized, the entire row of buttons gets re adjusted, which is not a pleasing visual effect.

My preference is for a template based solution, to avoid introducing new controls in order to provide overrides. The only problem with the hard coded size approach is internationalisation, other languages will increase the orginal size.

The solution I am going with is to set the minWidth in C# after the button's DesiredSize has been calculated. Note that Width is NaN even after the Button is rendered hence the use/existence of DesiredSize. Later I will try and XAMLize the C#.

Aidan Reel
A: 

You can increase the Padding at the same time you decrease the FontSize - this will cause the calculated height of the Button to remain the same:

<StackPanel>
    <Button Content="ABC">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="FontSize" Value="20"/>
                <Style.Triggers>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="FontSize" Value="12"/>
                        <Setter Property="Padding" Value="5"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
    <Button Margin="0,20" Content="123" FontSize="20"/>
    <Button Content="Do Re Mi" FontSize="20"/>
</StackPanel>

You can do the reverse and set a negative Padding if the FontSize is increasing, as well.

You could also use a binding from FontSize to Padding to accomplish the same thing in a general way, but if you're only dealing with a fixed set of FontSizes it would be easier to just hardcode it as above.

Robert Macnee
+4  A: 

A nice trick to isolate an element from its parent layout wise is to place the element in a Canvas

In the markup below there are two copies of your element The first is hidden and establishes the size of your control The second is visible but wrapped in a Canvas so its layout size does not affect the parent.

<Parent>
  <Grid>
    <Element Visibility="Hidden"/>
    <Canvas>
      <Element />
    </Canvas>
  <Grid>
</Parent>
Ifeanyi Echeruo
+2  A: 

There is absolutely NO need for hard-coded widths, crazy measure overrides, tricky bindings, or anything of that sort.

The solution is actually incredibly simple. Instead of changing the font size in a style trigger, create a simple control template for your button with a RenderTransform applied to the content presenter element. Add a ScaleTransform to the RenderTransform. Inside a IsPressed trigger definition set the vertical and horizontal scales on the ScaleTransform to a smaller ratio, say 0.8.

Using a RenderTransform will keep the layout of the pressed button the same with, so it won't influence the position of the other elements. By contrast, using a LayoutTransform would have actually caused the button container to shrink and the parent container's ArrangeOverride method would cause the adjacent buttons to move to fill the extra space.

I'm really busy right now so I'll leave the actual implementation up to you! ;-)

http://msdn.microsoft.com/en-us/library/system.windows.media.scaletransform.aspx

Jared