Xamarin.Forms+Prism Navigation 目标控件



我有一个由几种页面类型组成的Xamarin应用程序。我正在使用棱镜。

我希望应用的导航目标是主页内应用中的嵌套视图,而不是主页本身,以便将MainPage用作始终存在的外部框架,并且嵌套页面托管应用的导航服务。
通过这种方式,我可以始终存在一些控件(即后退/前进/主页)。 如何将NavigationService的"MainPage"配置为实际MainPage中的嵌套页面?
我是XF的新手,以前没有使用过NavigationPage,但它在这里有什么用吗?

你没有。Prism的导航服务将不支持您尝试执行的操作,因为INavigationService是基于Page的。 听起来你的方法非常不正统。 为什么不直接使用NavigationPage并在自定义渲染器中或作为工具栏项提供选项?

Prism的INavigationService不是为了做你想做的事情而设计的。 幸运的是,自定义视图是!您可以按照之前的建议进行操作,但我通常会避免创建自定义页面,而是创建一个具有自己的内容属性的自定义视图。

编辑:

这些术语可能会与 Xamarin 窗体特别混淆,特别是如果您不熟悉 MVVM 和 Xamarin 窗体,和/或已从其他平台上开发。

Xamarin Forms 所指的View在其他平台上更常被称为Control。在使用像Prism这样的MVVM框架时,这尤其令人困惑,因为我们的MVVMViews实际上是Xamarin FormsPages

虽然我们需要不时创建自定义类型的页面,但通常情况下,我们只是实现一些页面类型。例如,假设我有一个页面,我将用于登录页面:

登录页面.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
Title="{Binding Title}"
x:Class="MyAwesomeApp.Views.LoginPage">
<Grid BackgroundColor="{DynamicResource primary}">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="3*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.Resources>
<ResourceDictionary>
<Style TargetType="StackLayout">
<Setter Property="BackgroundColor" Value="White" />
<Setter Property="VerticalOptions" Value="FillAndExpand" />
</Style>
<Style TargetType="Entry">
<Setter Property="Margin" Value="40,10" />
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="20" />
<Setter Property="BackgroundColor" Value="{DynamicResource primaryDark}" />
<Setter Property="TextColor" Value="White" />
<Setter Property="BorderRadius" Value="5" />
<Setter Property="BorderWidth" Value="1" />
<Setter Property="BorderColor" Value="Black" />
</Style>
</ResourceDictionary>
</Grid.Resources>
<Image Source="logo.png" 
Aspect="AspectFit"
HorizontalOptions="Center"
VerticalOptions="Center" />
<StackLayout Grid.Row="1">
<Entry Text="{Binding UserName}" 
Placeholder="Enter your username"
x:Name="userNameEntry"
VerticalOptions="EndAndExpand" />
<Entry Text="{Binding Password}" 
Placeholder="Enter your password"
IsPassword="True"
x:Name="passwordEntry"
VerticalOptions="StartAndExpand" />
<Button Text="Submit"
Command="{Binding LoginCommand}" />
</StackLayout>
</Grid>
</ContentPage>

LoginPage.xaml.cs

public partial class LoginPage
{
public LoginPage()
{
InitializeComponent();
}
}

虽然 XAML 中有很多内容,但这只是一个内容页。它绝不是自定义页面。您会注意到此处背后的代码中绝对没有任何内容。例如,如果用户点击键盘上的 Done/Enter 并转到下一个字段或调用按钮单击,我可能会创建一些事件处理程序,但这仍然不会使其成为自定义页面。

有关"自定义页面"的示例,您可以查看XLabs ExtendedTabbedPage。您会注意到的一件事是,他们的 TabbedPage 版本上有几个新属性。当然,他们的页面只能因为渲染器而工作

坚持我已经展示的示例,假设我们想采用我在页面中创建的登录布局,并希望能够跨项目重用它,或者在我的应用程序的不同页面上重复使用它。然后我想做这样的事情:

LoginView.xaml

<?xml version="1.0" encoding="UTF-8"?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms" 
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
BackgroundColor="{DynamicResource primary}"
x:Name="grid"
x:Class="MyAwesomeApp.Controls.LoginView">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="3*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.Resources>
<ResourceDictionary>
<Style TargetType="StackLayout">
<Setter Property="BackgroundColor" Value="White" />
<Setter Property="VerticalOptions" Value="FillAndExpand" />
</Style>
<Style TargetType="Entry">
<Setter Property="Margin" Value="40,10" />
</Style>
<Style TargetType="Button">
<Setter Property="Margin" Value="20" />
<Setter Property="BackgroundColor" Value="{DynamicResource primaryDark}" />
<Setter Property="TextColor" Value="White" />
<Setter Property="BorderRadius" Value="5" />
<Setter Property="BorderWidth" Value="1" />
<Setter Property="BorderColor" Value="Black" />
</Style>
</ResourceDictionary>
</Grid.Resources>
<Image Source="logo.png" 
Aspect="AspectFit"
HorizontalOptions="Center"
VerticalOptions="Center" />
<StackLayout Grid.Row="1" BindingContext="{x:Reference grid}">
<Entry Text="{Binding UserName}" 
Placeholder="Enter your username"
x:Name="userNameEntry"
VerticalOptions="EndAndExpand" />
<Entry Text="{Binding Password}" 
Placeholder="Enter your password"
IsPassword="True"
x:Name="passwordEntry"
VerticalOptions="StartAndExpand" />
<Button Text="Submit"
Command="{Binding LoginCommand}" />
</StackLayout>
</Grid>

LoginView.xaml.cs

public partial class LoginView : Grid
{
public static readonly BindableProperty UserNameProperty =
BindableProperty.Create(nameof(UserName), typeof(string), typeof(LoginView), string.Empty);
public static readonly BindableProperty PasswordProperty =
BindableProperty.Create(nameof(Password), typeof(string), typeof(LoginView), string.Empty);
public static readonly BindableProperty LoginCommandProperty =
BindableProperty.Create(nameof(LoginCommand), typeof(ICommand), typeof(LoginView), null);
public LoginView()
{
InitializeComponent();
}
public string UserName
{
get { return (string)GetValue(UserNameProperty); }
set { SetValue(UserNameProperty,value); }
}
public string Password
{
get { return (string)GetValue(PasswordProperty); }
set { SetValue(PasswordProperty, value); }
}
public ICommand LoginCommand
{
get { return (ICommand)GetValue(LoginCommandProperty); }
set { SetValue(LoginCommandProperty, value); }
}
}

折射登录页面.xaml

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:MyAwesomeApp.Controls"
Title="{Binding Title}"
x:Class="MyAwesomeApp.Views.LoginPage">
<controls:LoginView UserName="{Binding UserName}" 
Password="{Binding Password}"
LoginCommand="{Binding LoginCommand}" />
</ContentPage>

您最终会得到的LoginView实际上是一个自定义控件。虽然它可能来自网格,但您通常并不关心我如何决定创建布局......你只关心我给你一些控制权,这些控制权具有可以附加到的UserNamePassword属性以及一些可以执行的LoginCommand。正是这种固有的差异实际上使其成为自定义视图。

我有一种方法。不完全是你想要的,但可以给你思考的食物。您可以使用SomeContent属性创建SomeBaseContentPage

public View SomeContent
{
set
{
someGrid.Children.Add(value);
}
}

然后从SomeBaseContentPage中获取SomeContentPageAXAML将您的特定内容放入财产<SomeBaseContentPage.SomeContent>

相关内容

  • 没有找到相关文章

最新更新