5

How can I use AdaptiveTrigger in Templated Control in Windows 10 (I use Windows 10 Pro Insider Preview Build 10074). Window.Current.SizeChanged event do not fire up when window size change. What is proper way to make fluid control? Here is what I try to do, but nothing happens when change size of screen:

XAML template:
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1">

    <Style TargetType="local:CustomControl1" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomControl1">
                    <Border>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="VisualSizeStates">

                                <VisualState x:Name="Small">
                                    <VisualState.StateTriggers>
                                        <AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0" />
                                    </VisualState.StateTriggers>
                                    <VisualState.Setters>

                                        <Setter Target="Rect.Fill" Value="Green"/>

                                    </VisualState.Setters>
                                </VisualState>

                                <VisualState x:Name="Big">
                                    <VisualState.StateTriggers>
                                        <AdaptiveTrigger MinWindowHeight="1000" MinWindowWidth="1000" />

                                    </VisualState.StateTriggers>
                                    <VisualState.Setters>
                                        <Setter Target="Rect.Fill" Value="Blue"/>
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Rectangle x:Name="Rect" Fill="Red" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
DobriBala
  • 132
  • 7

3 Answers3

4

The trick is that you have to put VisualStateManager with AdaptiveTrigger-s into root control of ControlTemplate otherwise it will not work.

Here is example:

Generic.xaml -->

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:AdaptiveLayoutExample">

    <Style TargetType="local:CustomControl1" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomControl1">
                    <Grid x:Name="RootGrid">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup>
                                <VisualState>
                                    <VisualState.StateTriggers>
                                        <AdaptiveTrigger MinWindowWidth="0"/>
                                    </VisualState.StateTriggers>
                                    <VisualState.Setters>
                                        <Setter Target="RootGrid.Background" Value="Yellow"/>
                                        <Setter Target="MyGrid.Background" Value="White"/>
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState>
                                    <VisualState.StateTriggers>
                                        <AdaptiveTrigger MinWindowWidth="600"/>
                                    </VisualState.StateTriggers>
                                    <VisualState.Setters>
                                        <Setter Target="RootGrid.Background" Value="Gray"></Setter>
                                        <Setter Target="MyGrid.Background" Value="Red"></Setter>
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Grid x:Name="MyGrid" Width="50" Height="50" Background="Black"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

MainPage.xaml -->

<Page
    x:Class="AdaptiveLayoutExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:AdaptiveLayoutExample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid>
        <local:CustomControl1 Width="100" Height="100"/>
    </Grid>
</Page>
Yuriy Pelekh
  • 168
  • 7
2

I don't think AdaptiveTriggers works in a style like that. The only place I've got it to work is directly in a UserControl or a Grid inside a Page. I know for sure they don't work in a DataTemplate. The VisualStateManager must be before the controls content too I believe. Try a different approach like this:

        <!--in app.xaml or something-->
    <ControlTemplate x:Key="controlTemplate1" TargetType="MyControl">
        <Border Background="Green"/>
    </ControlTemplate>
    <ControlTemplate x:Key="controlTemplate2"  TargetType="MyControl">
        <Border Background="Blue"/>
    </ControlTemplate>

    <!--in your page-->
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="visualStateGroup" >
                <VisualState>
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="720" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="control.Template" Value="{StaticResource controlTemplate1}"/>
                    </VisualState.Setters>
                </VisualState>

                <VisualState>
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="control.Template" Value="{StaticResource controlTemplate2}"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <MyControl x:Name="control" Template="{StaticResource controlTemplate1}"/>
    </Grid>

Not tested but let me know how that works out.

shady
  • 1,076
  • 2
  • 13
  • 33
  • Thank you! I find out that triggers work on page level. So I make two visual states of my control- GreenVisualState and BlueVisualState and one dependency properties GoToVisualState which change visual states. When the page size is change adaptive triggers set the properties to desired state. – DobriBala Jun 25 '15 at 10:35
  • Actually, AdaptiveTriggers will work inside a DataTemplate if you wrap your DataTemplate content with a UserControl. Check this answer: http://stackoverflow.com/questions/32088500/adaptivetrigger-and-datatemplate – Hrvoje Stanisic Dec 02 '15 at 12:22
0

Please note that when you don't have a "Big" VisualState to trigger the default settings you will keep having the overwritten ones from the other VisualStates. Might be obvious, but it took some time for me to grasp it.

GeorgiG
  • 1,018
  • 1
  • 13
  • 29