如何在Windows Phone中更改MenuFlyout的外观?

时间:2014-09-27 18:56:41

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

我主要阅读本文的所有内容,但我无法知道如何更改,例如MenuFlyout的入口主题转换,就像它出现在日历应用程序中一样。有一些像水平转弯而不是MenuFlyout的默认动画。

Windows phone calender app


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

1 个答案:

答案 0 :(得分:4)

MenuFlyout具有为TargetType =&#34; MenuFlyoutPresenter&#34;设置的标准样式。并且可以在.. \ 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 Border元素并将默认值设置为-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中定义新的故事板 - 而且它非常简单:

// ... 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度,这使得它可以通过漂亮的翻转动画从隐形变为可见,这是您正在寻找的。

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

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