Craig
Craig

Reputation: 1940

VisualStateManager doesn't update Grid properties when using nested Grid controls

Context: I want to use VisualStateManager to move a StackPanel to a different Grid column under certain conditions.

Problem: It seems that having nested Grid controls prevents my VisualState setter from being applied. In the example below (which has been simplified from the original code), the VisualState setter triggers if the OuterGrid is commented out, but won't fire when the OuterGrid is present.

Question: How can I trigger the VisualState setter when using nested grids?

Example:

<Grid x:Name="OuterGrid">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="12"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <StackPanel 
            Grid.Column="0"
            >
            <Button 
                x:Name="Button1"
                HorizontalAlignment="Stretch"
                Content="Button1"
                />
        </StackPanel>

        <StackPanel 
            x:Name="Button2"
            Grid.Column="2"
            >
            <HyperlinkButton
                Height="36"
                HorizontalAlignment="Stretch"
                >
                <TextBlock
                    Text="Button2"
                    />
            </HyperlinkButton>
        </StackPanel>

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="ButtonAlignments">
                <VisualState>
                    <!-- Move Button2 to the left column -->
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="600" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="Button2.(Grid.Column)" Value="0" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</Grid>

Upvotes: 0

Views: 126

Answers (1)

Mikolaj Kieres
Mikolaj Kieres

Reputation: 4405

You need to define your Visual States at the root level of your XAML tree, as per docs.

Just move the your <VisualStateManager.VisualStateGroups> into the OuterGrid. I changed your sample a bit - it's working with Visibility instead of the Grid.Column:

<Grid x:Name="OuterGrid">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="ButtonAlignments">
            <VisualState>
                <!-- Move Button2 to the left column -->
                <VisualState.Setters>
                    <!--<Setter Target="Button2.(Grid.Column)"
                                Value="0" />-->
                    <Setter Target="Button2.(UIElement.Visibility)"
                            Value="Visible" />
                </VisualState.Setters>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="600" />
                </VisualState.StateTriggers>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Grid>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="12" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0">
            <Button x:Name="Button1"
                    HorizontalAlignment="Stretch"
                    Content="Button1" />
        </StackPanel>

        <StackPanel x:Name="Button2"
                    Grid.Column="2"
                    Visibility="Collapsed">
            <HyperlinkButton Height="36"
                             HorizontalAlignment="Stretch">
                <TextBlock Text="Button2" />
            </HyperlinkButton>
        </StackPanel>

    </Grid>
</Grid>

Upvotes: 1

Related Questions