简体   繁体   中英

UWP setting Grid.Column with style not working

I'm developing a UWP app and trying to apply a style per control in code that would set the Grid.Column property, effectively to move the elements around the grid. However, my elements stay where they are, even though the animations run. Any setter besides Grid.* works, and I can see the styles being applied both through my code and through the live property window.

I know there are other ways to accomplish what I'm going for and I'll probably do one of those, but I want to know what's going on here. I'll post a sample of my page and the command that applies the styling:

MainPage.xaml

<Page
    x:Class="UWPApp.Scorekeeper.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UWPApp.Scorekeeper"
    xmlns:viewmodels="using:UWPApp.Scorekeeper.Models.ViewModels"
    xmlns:converters="using:UWPApp.Scorekeeper.Converters"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:mo="using:UWPApp.Scorekeeper.Models"
    mc:Ignorable="d"
    x:Name="MainPageElement"
    d:DesignHeight="600"
    d:DesignWidth="1024">



    <Page.Resources>
        <DataTemplate x:Key="GridHorizontalTemplate" x:DataType="local:MainPage">
            <Grid MinWidth="768" MinHeight="500" Background="{ThemeResource SystemControlBackgroundAccentBrush}" ManipulationMode="All">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="69*"/>
                    <ColumnDefinition Width="76*"/>
                    <ColumnDefinition Width="76*"/>
                    <ColumnDefinition Width="69*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="73*"/>
                    <RowDefinition Height="135*"/>
                    <RowDefinition Height="69*"/>
                    <RowDefinition Height="43*"/>
                </Grid.RowDefinitions>
                <Button Foreground="{ThemeResource SystemControlForegroundChromeMediumBrush}" Command="{Binding ElementName=MainPageElement, Path=EnterGoalCommand}" CommandParameter="{Binding ElementName=MainPageElement,Path=StateModel.HomeID}" x:Name="HomeGoalBtn" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1" Grid.Column="1" Margin="0,0.4,0,0" d:LayoutOverrides="LeftMargin, RightMargin" >
                    <Button.Resources>
                        <Style x:Key="FlippedStyle" TargetType="Button">
                            <Setter Property="Grid.Column" Value="2"/>
                        </Style>
                        <Storyboard x:Key="ToFlipAnimation">
                            <RepositionThemeAnimation FromHorizontalOffset="-487"/>
                        </Storyboard>
                        <Storyboard x:Key="FromFlipAnimation">
                            <RepositionThemeAnimation FromHorizontalOffset="487"/>
                        </Storyboard>
                    </Button.Resources>
                    <Viewbox Margin="40" Stretch="Uniform">
                        <TextBlock Text="Goal" FontSize="48" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
                    </Viewbox>
                </Button>
                <Button Foreground="{ThemeResource SystemControlForegroundChromeMediumBrush}" Command="{Binding ElementName=MainPageElement, Path=EnterGoalCommand}" CommandParameter="{Binding ElementName=MainPageElement,Path=StateModel.AwayID}" x:Name="AwayGoalBtn" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1" Grid.Column="2" Margin="0,0.4,-0.2,0" d:LayoutOverrides="LeftMargin, RightMargin" >
                    <Button.Resources>
                        <Style x:Key="FlippedStyle" TargetType="Button">
                            <Setter Property="Grid.Column" Value="1"/>
                        </Style>
                        <Storyboard x:Key="ToFlipAnimation">
                            <RepositionThemeAnimation FromHorizontalOffset="487"/>
                        </Storyboard>
                        <Storyboard x:Key="FromFlipAnimation">
                            <RepositionThemeAnimation FromHorizontalOffset="-487"/>
                        </Storyboard>
                    </Button.Resources>
                    <Viewbox Margin="40" Stretch="Uniform">
                        <TextBlock Text="Goal" FontSize="48" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Bottom" />
                    </Viewbox>
                </Button>
            </Grid>
        </DataTemplate>
    </Page.Resources>

    <ContentPresenter x:Name="MainContent" Margin="0,0,0,0" HorizontalAlignment="Stretch" d:LayoutOverrides="Width, Height" VerticalAlignment="Stretch">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState>
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="1000"></AdaptiveTrigger>
                    </VisualState.StateTriggers>

                    <VisualState.Setters>
                        <Setter Target="MainContent.ContentTemplate" Value="{StaticResource GridHorizontalTemplate}" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </ContentPresenter>
</Page>

MainPage.xaml.cs

public ICommand FlipScreen => new CommandHandler(() =>
        {
            if (!flipped)
            {
                flipped = true;
                foreach (var item in this.FindChildren<FrameworkElement>())
                {
                    object styleObject;
                    if (item.Resources.TryGetValue("FlippedStyle", out styleObject))
                    {
                        item.Style = (Style)styleObject;
                    }
                    object animationObject;
                    if (item.Resources.TryGetValue("ToFlipAnimation", out animationObject))
                    {
                        Storyboard board = animationObject as Storyboard;
                        if (board.GetCurrentState() != ClockState.Stopped)
                        {
                            board.Stop();
                        }
                        foreach (var subitem in board.Children)
                        {
                            Storyboard.SetTarget(subitem, item);
                        }
                        board.Begin();
                    }
                }
            }
            else
            {
                flipped = false;
                foreach (var item in this.FindChildren<FrameworkElement>())
                {
                    item.Style = null;
                    object animationObject;
                    if (item.Resources.TryGetValue("FromFlipAnimation", out animationObject))
                    {
                        Storyboard board = animationObject as Storyboard;
                        if (board.GetCurrentState() != ClockState.Stopped)
                        {
                            board.Stop();
                        }
                        foreach (var subitem in board.Children)
                        {
                            Storyboard.SetTarget(subitem, item);
                        }
                        board.Begin();
                    }
                }
            }
        });

FindChildren:

public static List<T> FindChildren<T>(this FrameworkElement element) where T : FrameworkElement
        {
            int childrenCount = VisualTreeHelper.GetChildrenCount(element);
            var children = new FrameworkElement[childrenCount];

            List<T> list = new List<T>();

            for (int i = 0; i < childrenCount; i++)
            {
                var child = VisualTreeHelper.GetChild(element, i) as FrameworkElement;
                children[i] = child;
                if (child is T)
                    list.Add(child as T);
            }

            for (int i = 0; i < childrenCount; i++)
                if (children[i] != null)
                {
                    var subChild = FindChildren<T>(children[i]);
                    if (subChild != null)
                        list.AddRange(subChild);
                }

            return list;
        }

Not sure if a default Button Style in the Resources of a Button would actually apply to that Button.

Better set the Style explicitly:

<Button ... >
    <Button.Style>
        <Style TargetType="Button">
            <Setter Property="Grid.Column" Value="2"/>
        </Style>
    </Button.Style>
    <Button.Resources>
        ...
    </Button.Resources>
    <Viewbox ...>
        ...
    </Viewbox>
</Button>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM