<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ChangeiOSBackButtonText.Views.MainPage"
Title="上頁文字變換">
<StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
<Label Text="Welcome to Xamarin Forms and Prism!" />
<Button Text="切換可動態變換按鈕文字" Command="{Binding SwithChangePageCommand}"/>
<Button Text="切換一般頁面" Command="{Binding SwithNextPageCommand}"/>
<Button Text="連續兩個頁面" Command="{Binding SwithTwoPageCommand}"/>
</StackLayout>
</ContentPage>
<?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:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="ChangeiOSBackButtonText.Views.CanChangePage"
xmlns:DynBtn="clr-namespace:ChangeiOSBackButtonText.AttachedProperties"
DynBtn:DynamicBackButtonTextAttached.SetBackButtonText="{Binding ThisBackText}"
xmlns:localViews="clr-namespace:ChangeiOSBackButtonText.Views"
Title="{Binding Title}">
<StackLayout
>
<Entry Text="{Binding Message}"/>
<Button Text="設定" Command="{Binding SetBackButtonTextCommand}"/>
<Button Text="切換中文" Command="{Binding SetChineseCommand}"/>
<Button Text="Switch English" Command="{Binding SetEnglishCommand}"/>
</StackLayout>
</ContentPage>
設計理念說明
NaviCustomPage 建立與加入一個可綁定屬性 DynamicBackButtonText
<?xml version="1.0" encoding="utf-8" ?>
<NavigationPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="ChangeiOSBackButtonText.Views.NaviCustomPage">
</NavigationPage>
public partial class NaviCustomPage : NavigationPage
{
#region DynamicBackButtonText 可綁定屬性 BindableProperty
public static readonly BindableProperty DynamicBackButtonTextProperty =
BindableProperty.Create("DynamicBackButtonText",
typeof(string),
typeof(NaviCustomPage),
"",
propertyChanged: OnDynamicBackButtonTextChanged
);
public string DynamicBackButtonText
{
set
{
SetValue(DynamicBackButtonTextProperty, value);
}
get
{
return (string)GetValue(DynamicBackButtonTextProperty);
}
}
private static void OnDynamicBackButtonTextChanged(BindableObject bindable, object oldValue, object newValue)
{
}
#endregion
public NaviCustomPage()
{
InitializeComponent();
}
}
指定使用來做頁面導航
protected override async void OnInitialized()
{
InitializeComponent();
await NavigationService.NavigateAsync("MDPage/NaviCustomPage/MainPage");
}
設計附加屬性 DynamicBackButtonTextAttached
public class DynamicBackButtonTextAttached
{
#region SetBackButtonText 附加屬性 Attached Property
public static readonly BindableProperty SetBackButtonTextProperty =
BindableProperty.CreateAttached(
propertyName: "SetBackButtonText",
returnType: typeof(string),
declaringType: typeof(ContentPage),
defaultValue: null,
propertyChanged: OnSetBackButtonTextChanged
);
public static void SetSetBackButtonText(BindableObject bindable, string entryType)
{
bindable.SetValue(SetBackButtonTextProperty, entryType);
}
public static string GetSetBackButtonText(BindableObject bindable)
{
return (string)bindable.GetValue(SetBackButtonTextProperty);
}
private static void OnSetBackButtonTextChanged(BindableObject bindable, object oldValue, object newValue)
{
ContentPage page = bindable as ContentPage;
if (page == null) return;
string oldString = oldValue as string;
string newString = newValue as string;
if (newString == null) return;
if(page is IDynamicChangeBackText)
{
ChangeBackButtonTextHelper.ChangeBackButtonText(newString);
}
}
#endregion
}
建立輔助支援方法,可以修改當前導航頁面上的 DynamicBackButtonText 屬性
public class ChangeBackButtonTextHelper
{
public static void ChangeBackButtonText(string newBackButtonText)
{
NaviCustomPage naviCustomPage = GetNaviCustomPage();
if (naviCustomPage != null)
{
naviCustomPage.DynamicBackButtonText = newBackButtonText;
};
}
public static string GetBackButtonText()
{
string result = "";
NaviCustomPage naviCustomPage = GetNaviCustomPage();
if (naviCustomPage != null)
{
result = naviCustomPage.DynamicBackButtonText;
}
return result;
}
public static NaviCustomPage GetNaviCustomPage()
{
NaviCustomPage naviCustomPage = null;
if (App.Current.MainPage is MasterDetailPage)
{
MasterDetailPage masterDetailPage = App.Current.MainPage as MasterDetailPage;
if (masterDetailPage.Detail is NaviCustomPage)
{
naviCustomPage = masterDetailPage.Detail as NaviCustomPage;
}
}
else if (App.Current.MainPage is NaviCustomPage)
{
naviCustomPage = App.Current.MainPage as NaviCustomPage;
}
return naviCustomPage;
}
}
對於要能夠變更回上頁按鈕文字的 ContentPage,需要實作 IDynamicChangeBackText
public interface IDynamicChangeBackText
{
}
public partial class CanChangePage : ContentPage, IDynamicChangeBackText
{
public CanChangePage()
{
InitializeComponent();
}
}
[assembly: ExportRenderer(typeof(NaviCustomPage), typeof(NaviCustomPageRenderer))]
namespace ChangeiOSBackButtonText.iOS.Renderers
{
public class NaviCustomPageRenderer : NavigationRenderer
{
UIBarButtonItem barButtonItem;
NaviCustomPage oldMyNaviPage;
NaviCustomPage newMyNaviPage;
protected override Task<bool> OnPushAsync(Page page, bool animated)
{
var retVal = base.OnPushAsync(page, animated);
if (page is IDynamicChangeBackText)
{
SetBackButtonOnPage(page);
}
return retVal;
}
protected override Task<bool> OnPopViewAsync(Page page, bool animated)
{
var retVal = base.OnPopViewAsync(page, animated);
if (page is IDynamicChangeBackText)
{
var stack = page.Navigation.NavigationStack;
var returnPage = stack[stack.Count - 2];
if (returnPage != null)
{
SetBackButtonOnPage(returnPage);
}
}
else
{
}
return retVal;
}
void SetBackButtonOnPage(Page page)
{
if (page is IDynamicChangeBackText)
{
string backButtonText = ChangeBackButtonTextHelper.GetBackButtonText();
SetImageTitleBackButton("Left2", backButtonText, -15);
}
else
{
}
}
void SetImageTitleBackButton(string imageBundleName, string buttonTitle, int horizontalOffset)
{
var topVC = this.TopViewController;
var backButtonImage = new UIBarButtonItem(
UIImage.FromBundle(imageBundleName),
UIBarButtonItemStyle.Plain,
(sender, args) =>
{
topVC.NavigationController.PopViewController(true);
});
var backButtonText = new UIBarButtonItem(
buttonTitle,
UIBarButtonItemStyle.Plain,
(sender, args) =>
{
topVC.NavigationController.PopViewController(true);
});
backButtonText.SetTitlePositionAdjustment(new UIOffset(horizontalOffset, 0), UIBarMetrics.Default);
UIBarButtonItem[] buttons = new UIBarButtonItem[2];
buttons[0] = backButtonImage;
buttons[1] = backButtonText;
topVC.NavigationItem.LeftBarButtonItems = buttons;
}
void SetDefaultBackButton()
{
this.TopViewController.NavigationItem.LeftBarButtonItems = null;
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
oldMyNaviPage = (NaviCustomPage)e.OldElement;
newMyNaviPage = (NaviCustomPage)e.NewElement;
if (oldMyNaviPage != null)
{
oldMyNaviPage.PropertyChanged -= OnElementPropertyChanged;
}
if (newMyNaviPage != null)
{
newMyNaviPage.PropertyChanged += OnElementPropertyChanged;
}
}
private void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "DynamicBackButtonText")
{
UpdateBackButtonTitleText();
}
}
private void UpdateBackButtonTitleText()
{
string backTitle = "";
backTitle= ChangeBackButtonTextHelper.GetBackButtonText();
if (this.NavigationBar.Items.Count() > 1)
{
this.TopViewController.NavigationItem.LeftBarButtonItems[1].Title = backTitle;
}
}
}
}