有什么方法可以修改子类,以便所有超类都继承更改?

时间:2018-07-26 15:33:56

标签: c# xamarin inheritance

我的确切问题是,我正在尝试向Xamarin应用程序中的所有页面全局添加逻辑。

也就是说,我正在尝试创建一个“我的页面”,所有我的页面都继承自该页面。我在此“母版页”中放置了页眉/页脚和导航逻辑,因此不必在每个页面上都重写它。 ...之所以说是“母版页”,是因为Xamarin有一个称为master-detail的页面,而这并不是我在说的。我正在谈论母版页的概念,就像您可能在ASP.NET Web窗体中使用的那样。与Xamarin中最接近的类似物是<html> <body> <h1>The Alcoves</h1> <table width="50%" cellspacing="20"> <tr> <a href="index.html"><td> Reviews</td></a> <a href="index%203.html"><td> Features</td></a> <a href="index%202.html"><td> About Us</td></a> </tr> </table> <div id="twitterbird"><a href="https://twitter.com/AlcovesFilm"> <img src="twitter%20bird.png" height="40" width="40" alt="Twitter"> </a></div> </body> </html>,您只需做一些工作,就能获得与您实际将其视为母版页相同的效果。看起来像这样:

App.xaml(母版页的正文)

<ControlTemplate>

MyPage.xaml(母版页中的内容)

...
<Application.Resources>
    <ResourceDictionary>
        <ControlTemplate x:Key="MainPageTemplate">
            <StackLayout>
                <Label Text="{TemplateBinding HeaderText}" />
                <ContentPresenter /> <!-- this is a placeholder for content -->
                <Label Text="{TemplateBinding FooterText}" />
            </StackLayout>
        </ControlTemplate>
    </ResourceDictionary>
</Application.Resources>
...

MyMasterPage.cs(共享的页眉/页脚和导航逻辑)

<!-- Translation: this page inherits from CoolApp.Views.MyMasterPage.cs -->
<Views:MyMasterPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:Views="clr-namespace:CoolApp.Views"
            x:Class="CoolApp.Views.MyPage"
            ControlTemplate="{StaticResource MainPageTemplate}">
    <Label Text="I am the content" />
</Views:MyMasterPage>

在我需要使用// it inherits from ContentPage here, which works fine. so long as your app only uses ContentPages public class MyMasterPage : ContentPage, INotifyPropertyChanged { ... public static BindableProperty HeaderTextProperty; public string HeaderText { get { return (string)GetValue(HeaderTextProperty); } set { HeaderTextProperty = BindableProperty.Create("HeaderText", typeof(string), typeof(SearchPage), value); OnPropertyChanged("HeaderText"); } } // footer logic // navigation logic ... } 以外的页面类型之前,此母版页设置对我非常有用。具体来说,我需要一个ContentPage才能以完全相同的方式工作。在上面的代码中,我可以让CarouselPage继承自MyMasterPage.cs而不是CarouselPage,这很好,除非我在两个不同的母版页中具有全局页眉/页脚和导航逻辑。我不能只是将逻辑放在从ContentPage继承的母版页中,因为这样我的页面将是Page类型,而不是PageContentPage。但是,如果我可以直接修改CarouselPage,那么PageContentPage都会得到我的更改。也许看起来像这样?

enter image description here

我希望这很清楚,但是如果不是我要问的问题,我如何才能将页眉和页脚以及导航逻辑全部放入一个母版页中?

2 个答案:

答案 0 :(得分:3)

我听说过为超类添加功能并考虑扩展。我对c#一无所知,但是例如,您可以迅速将行为添加到现有类型中。但是,这不能通过修改孩子来实现,但是您可以赋予超类新的能力。不知道这是否正是您在用例中所需要的 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods

答案 1 :(得分:2)

我与nbpeth带有扩展名的原因相同

如果要向所有页面(此处为MyContentPageMyCarouselPage)添加属性,则可能需要为每个页面创建一个母版页,而不是仅一个母版页,但是将扩展类中的导航逻辑

您可以尝试以下操作(我不保证此代码有效,我手边没有Xamarin设置

public static class PageExtensions
{
    public string GetMyValue(this Page page, BindableProperty headerTextProperty)
    {
        return (string)page.GetValue(headerTextProperty);
    }

    public void SetMyValue(this Page page, out BindableProperty headerTextProperty, string value)
    {
        headerTextProperty = null;
        if (page is INotifyPropertyChanged notifyPage)
        {
            headerTextProperty = BindableProperty.Create("HeaderText", typeof(string), typeof(SearchPage), value);
            notifyPage.OnPropertyChanged("HeaderText");
        }
    }
}

public class MyMasterContentPage : ContentPage
{
    // ...
    public BindableProperty HeaderTextProperty;

    public string HeaderText
    {
        get { return GetMyValue(HeaderTextProperty); }
        set { SetMyValue(out HeaderTextProperty, value); }
    }
}

public class MyContentPage : MyMasterContentPage, INotifyPropertyChanged
{
}

public class MyMasterCarouselPage : CarouselPage
{
    // ...
    public BindableProperty HeaderTextProperty;

    public string HeaderText
    {
        get { return GetMyValue(HeaderTextProperty); }
        set { SetMyValue(out HeaderTextProperty, value); }
    }
}

public class MyCarouselPage : MyMasterCarouselPage, INotifyPropertyChanged
{
}

您仍然会有一些重复的代码,但没有重复的逻辑