我的确切问题是,我正在尝试向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
类型,而不是Page
和ContentPage
。但是,如果我可以直接修改CarouselPage
,那么Page
和ContentPage
都会得到我的更改。也许看起来像这样?
我希望这很清楚,但是如果不是我要问的问题,我如何才能将页眉和页脚以及导航逻辑全部放入一个母版页中?
答案 0 :(得分:3)
我听说过为超类添加功能并考虑扩展。我对c#一无所知,但是例如,您可以迅速将行为添加到现有类型中。但是,这不能通过修改孩子来实现,但是您可以赋予超类新的能力。不知道这是否正是您在用例中所需要的 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods
答案 1 :(得分:2)
我与nbpeth带有扩展名的原因相同
如果要向所有页面(此处为MyContentPage
和MyCarouselPage
)添加属性,则可能需要为每个页面创建一个母版页,而不是仅一个母版页,但是将扩展类中的导航逻辑
您可以尝试以下操作(我不保证此代码有效,我手边没有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
{
}
您仍然会有一些重复的代码,但没有重复的逻辑