TheBard
TheBard

Reputation: 346

Change a Style based on Visual State

"Blend makes it simple to setup Visual States based on say minWindowWidth. But it would be very nice to have state-based Styles defined for TextBlock elements, say with tag="header", tag="body", and have the Setter change the Style automatically."

Maybe I wasn't explicit enough in my initial question, let me rephrase this.

I am resizing my application window from say Landscape to Portrait. My VisualStateManager has setters which adjust the page properties based on the new minimum width.

I have multiple TextBlocks (header,body, etc) and other controls with .Text (ToggleSwitch), that I want to automatically adjust FontSize based on the new width.

Aside from manually setting every single control by name in all the states, is there a way to have the VisualStateManager do it automatically for each 'type' of Text(body/header/etc)? My work around at the moment is to DataBind a Style for every .Text control and have the ViewModel do all the scaling. That works, but this is really something Blend is made for, right? So I must be missing the obvious way everyone is using.

Thanks for all the good comments so far.

        <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="VisualStateGroup">
            <VisualState x:Name="PhonePortrait">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="{StaticResource NarrowMinWidth}"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="SwitchStackPanel.(StackPanel.Orientation)" Value="Vertical"/>
                    <!-- Setter to change all Body textblocks to FontSize=8-->
                    <!-- Setter to change all Header textblocks to FontSize=10-->
                    <!-- Setter to change all ToggleSwitch.Text to FontSize=8-->
                    <!-- etc..-->

Upvotes: 0

Views: 1880

Answers (1)

Ginger Ninja
Ginger Ninja

Reputation: 797

You could use a global style. That utilizes triggers based on the Tag.

<Style TargetType="{x:Type TextBlock}">
   <!--Default Setters Here-->
   <Setter Property="Background" Value="White"/>
   <Style.Triggers>
       <Trigger Property="Tag" Value="body">
            <Setter Property="Background" Value="Gray"/>
            <!--Insert desired state setters here-->
       </Trigger>
       <Trigger Property="Tag" Value="header">
            <Setter Property="Background" Value="DarkGray"/>
            <!--Insert desired state setters here-->
       </Trigger>
   </Style.Triggers>
</Style>

You can then have a default state, and Triggered setters than only affect a Textblock when an applicable tag is attached.

If you already have other styles or want to have a selection process, you may want to add a key and then use BasedOn within the style.

Upvotes: 1

Related Questions