作为替代方案,您可以在 OnNaviged 方法中设置 titleview :
在 AppShell.xaml 中,定义标签的名称
<Shell.TitleView>
<Grid ColumnDefinitions="*,200">
<Label BindingContext="{x:Reference shellMain}" x:Name="mylabel" FontSize="Large" TextColor="White" />
<ActivityIndicator IsRunning="{Binding IsBusy}" Color="Orange" Grid.Column="1" HorizontalOptions="End" />
</Grid>
</Shell.TitleView>
在AppShell.xaml.cs中,重写OnNaviged方法,获取当前项目
protected override void OnNavigated(ShellNavigatedEventArgs args)
{
base.OnNavigated(args);
var shellItem = Shell.Current?.CurrentItem;
string title = shellItem?.Title;
int iterationCount = 0;
while (shellItem != null
&& title == null)
{
title = shellItem.Title;
shellItem = shellItem.CurrentItem;
if (iterationCount > 10)
break; // max nesting reached
iterationCount++;
}
myLabel.Text = title;
}
希望它对你有用。
我正在尝试同样的方法来修改 TitleView 的外观。它可以在 iOS 上运行,尽管那里还有另一个错误。但在 Android 上我遇到了同样的问题。在前进导航中,它会更新标题,但当您按后退按钮时,标题不会更新。我已经打开了一个问题并添加了一个存储库。
https://github.com/dotnet/maui/issues/12416#issuecomment-1372627514
还有其他方法可以修改TitleView的外观吗?
我使用视图模型开发了这个解决方法,主要不是为了提供 MVVM 解决方案,而是因为其他建议的答案对我不起作用。 (我怀疑 Liqun Shen 2 月 15 日针对他自己的问题的评论中的建议会起作用。但我没有注意到这一点,直到我自己修复)。
当前页面的标题保存在可由 shell 的视图模型和每个内容页面的视图模型访问的类中:
public class ServiceHelper {
private static ServiceHelper? _default;
public static ServiceHelper Default => _default ??= new ServiceHelper();
internal string CurrentPageTitle { get; set; } = string.Empty;
}
shell 中每个内容页面的视图模型提供其页面标题。为了促进这一点,大部分工作都是由基本视图模型完成的,它们都是从该模型派生而来的:
public abstract class ViewModelBase(string title) : ObservableObject {
private ServiceHelper? _serviceHelper;
public string Title { get; } = title;
internal ServiceHelper ServiceHelper {
get => _serviceHelper ??= ServiceHelper.Default;
set => _serviceHelper = value; // For unit testing.
}
public virtual void OnAppearing() {
ServiceHelper.CurrentPageTitle = Title;
}
}
每个 shell 内容页面视图模型只需要让其基础视图模型知道它的标题:
public class LocationsViewModel : ViewModelBase {
public LocationsViewModel() : base("Locations") {
}
}
每个 shell 内容页面都需要在其视图模型中触发所需的事件响应方法:
public partial class LocationsPage : ContentPage {
private LocationsViewModel? _viewModel;
public LocationsPage() {
InitializeComponent();
}
private LocationsViewModel ViewModel =>
_viewModel ??= (LocationsViewModel)BindingContext;
protected override void OnAppearing() {
base.OnAppearing();
ViewModel.OnAppearing();
}
}
Shell 的视图模型为标题栏提供当前页面的标题:
public class AppShellViewModel() : ViewModelBase(Global.ApplicationTitle) {
private string _currentPageTitle = string.Empty;
public string CurrentPageTitle {
get => _currentPageTitle;
set {
_currentPageTitle = value;
OnPropertyChanged();
}
}
public void OnNavigated() {
CurrentPageTitle = ServiceHelper.CurrentPageTitle;
}
}
Shell 需要在其视图模型中触发所需的事件响应方法:
public partial class AppShell : Shell {
private AppShellViewModel? _viewModel;
public AppShell() {
InitializeComponent();
}
private AppShellViewModel ViewModel =>
_viewModel ??= (AppShellViewModel)BindingContext;
protected override void OnNavigated(ShellNavigatedEventArgs args) {
base.OnNavigated(args);
ViewModel.OnNavigated();
}
}
最后,Shell 的 XAML 在标题栏/导航栏上显示由 Shell 视图模型提供的当前页面的标题:
<Shell.TitleView>
<HorizontalStackLayout VerticalOptions="Fill">
<Image Source="falcon_svg_repo_com.png"
HeightRequest="50"/>
<Label x:Name="CurrentPageTitleLabel"
Text="{Binding CurrentPageTitle}"
FontSize="24"
Margin="10,0"
VerticalTextAlignment="Center"/>
</HorizontalStackLayout>
</Shell.TitleView>