Inheritance 如何在应用程序中的所有页面中实现类似于选项卡的菜单,而无需反复编写相同的代码

Inheritance 如何在应用程序中的所有页面中实现类似于选项卡的菜单,而无需反复编写相同的代码,inheritance,windows-phone-7,event-handling,Inheritance,Windows Phone 7,Event Handling,我希望在我的应用程序中有一个跨页面的菜单。实现这一点的一种方法是在应用程序的每个页面中声明菜单布局和EventHandler,但这是一种糟糕的做法 我曾尝试实现一个页面,该页面声明菜单和EventHandler,然后从中继承所有其他内容,如下面的示例所示,但它似乎不适用于EventHandler。有没有人有这方面的经验,或者知道其他更有效的方法 <InheritedPage:PhoneApplicationPageDerived x:Class="InheritedPage.Ma

我希望在我的应用程序中有一个跨页面的菜单。实现这一点的一种方法是在应用程序的每个页面中声明菜单布局和EventHandler,但这是一种糟糕的做法

我曾尝试实现一个页面,该页面声明菜单和EventHandler,然后从中继承所有其他内容,如下面的示例所示,但它似乎不适用于EventHandler。有没有人有这方面的经验,或者知道其他更有效的方法

<InheritedPage:PhoneApplicationPageDerived 
    x:Class="InheritedPage.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:InheritedPage="clr-namespace:InheritedPage;assembly=InheritedPage"
    xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}">

    <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitleGrid is the name of the application and page title-->
        <Grid x:Name="TitleGrid" Grid.Row="0">
            <TextBlock Text="MY APPLICATION" x:Name="textBlockPageTitle" Style="{StaticResource PhoneTextPageTitle1Style}"/>
            <TextBlock Text="page title" x:Name="textBlockListTitle" Style="{StaticResource PhoneTextPageTitle2Style}"/>
        </Grid>

        <!--ContentGrid is empty. Place new content here-->
        <Grid x:Name="ContentGrid" Grid.Row="1">
            <Button Content="Virtual" Height="70" HorizontalAlignment="Left" Name="button1" VerticalAlignment="Top" Width="160" Click="SomeVirtualMethod" />
            <Button Content="Base" Height="70" HorizontalAlignment="Left" Margin="320,0,0,0" Name="button2" VerticalAlignment="Top" Width="160" Click="SomeBaseMethod" />
        </Grid>
    </Grid>

</InheritedPage:PhoneApplicationPageDerived>





using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Diagnostics;

namespace InheritedPage {

    public class PhoneApplicationPageBase : PhoneApplicationPage {

        public PhoneApplicationPageBase() {
        }

        public virtual void SomeVirtualMethod(object sender, RoutedEventArgs e) {
            Debug.WriteLine("PhoneApplicationPageBase Virtual Method");
        }

    }

    public class PhoneApplicationPageDerived : PhoneApplicationPageBase {

        public PhoneApplicationPageDerived() {
        }

        public override void SomeVirtualMethod(object sender, RoutedEventArgs e) {
            Debug.WriteLine("PhoneApplicationPageDerived Override Method");
        }

    }

    public partial class MainPage : PhoneApplicationPageDerived {
        public MainPage() {
            InitializeComponent();

            SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
        }


        // 1. COMMENT OUT THIS METHOD DECLARATION to see virtual inherited methods 
        // break Application.LoadComponent in the generated MainPage.g.cs

        public override void SomeVirtualMethod(object sender, RoutedEventArgs e) {
            Debug.WriteLine("MainPage Override Method");
        }


        // 2. MOVE THIS METHOD DECLARATION into PhoneApplicationPageBase to see non virtual inherited 
        // methods break Application.LoadComponent in the generated MainPage.g.cs

        public void SomeBaseMethod(object sender, RoutedEventArgs e) {
            Debug.WriteLine("PhoneApplicationPageBase Base Method");
        }


    }
}

使用制度;
使用System.Collections.Generic;
使用System.Linq;
Net系统;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Animation;
使用System.Windows.Shapes;
使用Microsoft.Phone.Controls;
使用系统诊断;
命名空间继承页{
公共类PhoneApplicationPageBase:PhoneApplicationPage{
公用电话应用程序PageBase(){
}
公共虚拟void SomeVirtualMethod(对象发送方,路由目标){
WriteLine(“PhoneApplicationPageBase虚拟方法”);
}
}
公共类PhoneApplicationPage派生:PhoneApplicationPageBase{
公用电话应用程序页面派生(){
}
public override void SomeVirtualMethod(对象发送方,RoutedEventArgs e){
WriteLine(“PhoneApplicationPageDelivered覆盖方法”);
}
}
公共部分类主页面:PhoneApplicationPageDerived{
公共主页(){
初始化组件();
SupportedOrientations=SupportedPageOrientation.纵向| SupportedPageOrientation.横向;
}
//1.注释掉此方法声明以查看虚拟继承的方法
//在生成的MainPage.g.cs中中断Application.LoadComponent
public override void SomeVirtualMethod(对象发送方,RoutedEventArgs e){
WriteLine(“主页覆盖方法”);
}
//2.将此方法声明移动到PhoneApplicationPageBase中以查看非虚拟方法
//方法在生成的MainPage.g.cs中中断Application.LoadComponent
公共void SomeBaseMethod(对象发送方,RoutedEventArgs e){
WriteLine(“PhoneApplicationPageBase方法”);
}
}
}

在Silverlight中创建真正定制的用户界面时要小心……Microsoft对Silverlight应用程序的外观和感觉非常挑剔。他们显然更宽容XNA应用程序

为了回答您的问题,我的方法是声明一个静态类,该类包含持久化菜单中的菜单项,然后为菜单创建一个自定义控件,该控件通过访问该静态数据来填充自己。然后,只需将这些控件中的一个添加到希望其持久化的每个页面


我有一种感觉,这可能会遭到微软的回击,但你绝对可以试一试。

谢谢你,这是一个非常有趣的角度来看待这个问题。你能想出任何方法来实现符合MS WP7 UI指南的“全局”菜单功能吗?可能……如果它足够小,它可能会在全景图的多个页面上持续存在。但是,我猜他们会说这违背了WP7体验的精神。