【问题标题】:UWP setting Grid.Column with style not workingUWP 设置 Grid.Column 样式不起作用
【发布时间】:2016-10-13 22:26:03
【问题描述】:

我正在开发一个 UWP 应用程序并尝试在代码中为每个控件应用一种样式,该样式将设置 Grid.Column 属性,从而有效地在网格周围移动元素。但是,即使动画运行,我的元素仍保留在原处。除了 Grid.* 之外的任何设置器都可以工作,我可以通过我的代码和实时属性窗口看到正在应用的样式。

我知道还有其他方法可以实现我的目标,我可能会做其中一种,但我想知道这里发生了什么。我将发布我的页面示例和应用样式的命令:

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();
                    }
                }
            }
        });

找孩子:

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;
        }

【问题讨论】:

    标签: c# xaml uwp uwp-xaml


    【解决方案1】:

    不确定按钮资源中的默认按钮样式是否真的适用于该按钮。

    最好明确设置样式:

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

    【讨论】:

    • 注意 FlipScreen 命令,该命令在每个拥有它的元素上设置element.Style = element.Resources["FlippedStyle"]
    • 样式必须仅在命令运行时应用,否则应保持其原始值。
    猜你喜欢
    • 2016-02-08
    • 1970-01-01
    • 2017-06-25
    • 2015-07-26
    • 1970-01-01
    • 2022-01-26
    • 2015-02-23
    相关资源
    最近更新 更多