Search code examples
xamluwpwin-universal-appwinrt-xamlwindows-10-mobile

VisualStateManager not setting attached properties Grid.Row and Grid.ColumnSpan in UWP application


I'm trying to change some attached properties using the VisualStateManager in a Windows 10 Universal App project but the setters aren't working. It's not setting the attached properties of my TopBarGrid element.

If you look below I'm using the parentheses notation in order to change the Grid.Row and Grid.ColumnSpan properties. But when I run the app, the properties are not being set when I enlargen the width. I'm expecting the Grid to move to that position.

Here is my code:

<Grid>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="wideState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="641" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="splitView.DisplayMode" Value="Inline"/>
                    <Setter Target="splitView.IsPaneOpen" Value="True"/>
                    <Setter Target="togglePaneButton.Visibility" Value="Collapsed"/>
                    <Setter Target="appHeader.Margin" Value="0,0,0,0"/>
                    <Setter Target="PaneHeader.Margin" Value="6,12,0,0"/>
                    <Setter Target="TopBarGrid.(Grid.Column)" Value="0"/>
                    <Setter Target="TopBarGrid.(Grid.RowSpan)" Value="2"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="narrowState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="0" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="splitView.DisplayMode" Value="Overlay"/>
                    <Setter Target="togglePaneButton.Visibility" Value="Visible"/>
                    <Setter Target="PaneHeader.Margin" Value="60,12,0,0"/>
                    <Setter Target="searchForInfoBox.Width" Value="270"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Grid.RowDefinitions>
        <RowDefinition x:Name="TopRowHeight" Height="80"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="60"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid x:Name="TopBarGrid" Grid.Row="0" Grid.ColumnSpan="2">
        <toolbars:TopHorizontalToolBar/>
    </Grid>
    <Grid x:Name="LeftBarGrid" Grid.Column="0" Grid.RowSpan="2" Visibility="Collapsed">
        <toolbars:VerticalToolBar />
    </Grid>

Solution

  • Your code looks fine, however, in both states, you are setting the Row and ColumnSpan of the TopBarGrid to the same values. That's why you won't see any changes.

    Try removing one set from one state.


    The reason you still don't see any changes is most likely because there's something wrong with your Setters in your narrowState.

    Try the following code, note that the TopBarGrid behaves correctly.

    <Grid x:Name="LayoutRoot">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState x:Name="wideState">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="641" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="TopBarGrid.(Grid.Column)" Value="0" />
                        <Setter Target="TopBarGrid.(Grid.RowSpan)" Value="2" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="narrowState">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="TopBarGrid.Background" Value="Green" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition x:Name="TopRowHeight" Height="80" />
                <RowDefinition Height="*" />
                <RowDefinition Height="60" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid x:Name="TopBarGrid" Grid.Row="0" Grid.ColumnSpan="2" Background="Red" />
                <Grid x:Name="LeftBarGrid" Grid.Column="0" Grid.RowSpan="2" Visibility="Collapsed" />
        </Grid>
    </Grid>
    

    But as soon as I throw in more Setters (e.g. <Setter Target="PaneHeader.Margin" Value="60,12,0,0" />) to the narrowState, it stops working. I know, PaneHeader wasn't even defined in my test page! But it also tells me that the VSM simply swallows the error for some reason.

    So, try removing your Setters and adding them back one to one to locate the bugged one. Then it would be a simple fix.