【问题标题】:How to change the appearance of a MenuFlyout in Windows Phone?如何更改 Windows Phone 中 MenuFlyout 的外观?
【发布时间】:2014-09-27 18:56:41
【问题描述】:

我阅读了这篇文章的大部分内容,但我就是不知道如何进行更改,例如MenuFlyout的入口主题过渡,就像它出现在日历应用程序中一样。有类似水平转弯的东西,而不是 MenuFlyout 的默认动画。


<MenuFlyout>
   <MenuFlyout.MenuFlyoutPresenterStyle>
       <Style...../>
   </MenuFlyout.MenuFlyoutPresenterStyle>
   <MenuFlyoutItem Text="Test"/>
</MenuFlyout>

C#:

 MenuFlyout mf = (MenuFlyout)this.Resources["AddButtonFlyout"];
 mf.Placement = FlyoutPlacementMode.Bottom;
 mf.ShowAt(this.CommandBar);

【问题讨论】:

    标签: c# windows xaml user-interface windows-phone-8.1


    【解决方案1】:

    MenuFlyout 有一个为 TargetType="MenuFlyoutPresenter" 设置的标准样式,可以在 ..\Program Files (x86)\Windows Phone Kits\8.1\Include\abi\Xaml\Design\generic.xaml 中找到(我不会在这里复制/粘贴,因为它很长)。此 Style 定义了一个 ControlTemplate,您可以对其进行修改以设置 MenuFlyout 在更改为 BottomPortrait VisualState 时的行为方式。

    从我在日历应用中看到的情况来看,MenuFlyout 在您打开时会翻转。在预定义样式中,它首先显示上边框,然后从上到下绘制其余部分。

    因此,首先您需要将整个样式复制到您的资源中。然后,您需要找到 BottomPortrait VisualState 并清除 Storyboard 中的所有内容,以便能够从头开始定义自己的内容。

    我将使用 PlaneProjection 类 - 它提供了您正在寻找的那种 3D 效果。我将它添加到 CenterBorder 边框元素并将默认值设置为 -90。我将其设置为 -90,因为这意味着它垂直于屏幕,因此 MenuFlyout 在首次显示时不可见。

    // ... rest of the code
    <Border x:Name="CenterBorder" FlowDirection="LeftToRight" BorderBrush="{TemplateBinding Background}">
        <Border.Projection>
            <PlaneProjection RotationX="-90"/>
        </Border.Projection>
    // ... rest of the code
    

    下一步(也是最后一步)是在 BottomPortrait VisualState 中定义新的 Storyboard,如前所述 - 这非常简单:

    // ... rest of the code
    <VisualState x:Name="BottomPortrait">
        <Storyboard>
            <DoubleAnimation Duration="0:0:0.18" 
                             To="0" 
                             Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" 
                             Storyboard.TargetName="CenterBorder" />
         </Storyboard>
    </VisualState>
    // ... rest of the code
    

    它只是在很短的时间内将边框从 -90 度设置为 0 度,这使得它通过漂亮的翻转动画从不可见变为可见,这正是您所寻找的。​​p>

    样式(为简洁起见省略了不相关的部分 - 你应该仍然拥有它们!):

    <Style TargetType="MenuFlyoutPresenter">
        <!-- OTHER PROPERTY SETTERS -->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="MenuFlyoutPresenter">
                    <Border x:Name="OuterBorder" FlowDirection="LeftToRight" BorderBrush="{TemplateBinding BorderBrush}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="PlacementStates">
                                <VisualState x:Name="None" />
                                <VisualState x:Name="TopPortrait">
                                    <!-- TOP PORTRAIT STORYBOARD -->
                                </VisualState>
                                <VisualState x:Name="BottomPortrait">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0:0:0.18" 
                                                         To="0" 
                                                         Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" 
                                                         Storyboard.TargetName="CenterBorder" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="LeftLandscape">
                                    <!-- LEFT LANDSCAPE STORYBOARD -->
                                </VisualState>
                                <VisualState x:Name="RightLandscape">
                                    <!-- RIGHT LANDSCAPE STORYBOARD -->
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border.RenderTransform>
                            <ScaleTransform x:Name="OuterScaleTransform" />
                        </Border.RenderTransform>
                        <Border x:Name="CenterBorder" FlowDirection="LeftToRight" BorderBrush="{TemplateBinding Background}">
                            <Border.Projection>
                                <PlaneProjection RotationX="-90"/>
                            </Border.Projection>
                            <StackPanel x:Name="InnerBorder" FlowDirection="{TemplateBinding FlowDirection}" Background="{TemplateBinding Background}">
                                <StackPanel.RenderTransform>
                                    <ScaleTransform x:Name="InnerScaleTransform" />
                                </StackPanel.RenderTransform>
                                <ItemsPresenter x:Name="ItemsPresenter" Margin="{TemplateBinding Padding}" FlowDirection="{TemplateBinding FlowDirection}" />
                            </StackPanel>
                        </Border>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    编辑:

    最好在框架上显示 MenuFlyout。

    MenuFlyout mf = (MenuFlyout)this.Resources["AddButtonFlyout"];
    mf.Placement = FlyoutPlacementMode.Bottom;
    
    Frame fr = Window.Current.Content as Frame;
    mf.ShowAt(fr);
    

    【讨论】:

    • 谢谢,但我很确定我做错了什么,因为这种样式没有任何显示,只是 UI 的其余部分缩小了一点。我编辑了我的问题以显示我尝试过的内容。
    • @Cort3vl 您是否将 MenuFlyout 位置设置为 FlyoutPlacementMode.Bottom?
    • @Cort3vl 您正在显示 AddButtonFlyout,但您在问题中附加的 MenuFlyout 没有该键。
    • 对不起,这只是问题中的一个错误。我试图缩短它。在我在 Visual Studio 中的实际代码中,MenuFlyout 具有键“AddButtonFlyout”。
    • @Cort3vl 尝试在当前帧而不是 CommandBar 上显示它。我已经编辑了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 2016-05-01
    • 1970-01-01
    • 2012-08-20
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多