Xamarin.Forms
Xamarin.Formsでのナビゲーション
サーチ…
備考
Xamarin.Formsのナビゲーションは、階層型とモーダルの2つの主要なナビゲーションパターンに基づいています。
階層的なパターンは、ユーザがページのスタック内を下に移動し、「戻る」/「上へ」ボタンを押すことを可能にする。
モーダルパターンは、ユーザーからの特定のアクションを必要とする割り込みページですが、通常キャンセルボタンを押すとキャンセルできます。通知、アラート、ダイアログボックス、登録/編集ページなどの例があります。
ビューモデルからのINavigationの使用
最初のステップは、ビューモデルで使用するナビゲーションインタフェースを作成することです。
public interface IViewNavigationService
{
void Initialize(INavigation navigation, SuperMapper navigationMapper);
Task NavigateToAsync(object navigationSource, object parameter = null);
Task GoBackAsync();
}
Initialize
メソッドでは、カスタムのマッパーを使用して、関連付けられたキーでページタイプのコレクションを保持します。
public class SuperMapper
{
private readonly ConcurrentDictionary<Type, object> _typeToAssociateDictionary = new ConcurrentDictionary<Type, object>();
private readonly ConcurrentDictionary<object, Type> _associateToType = new ConcurrentDictionary<object, Type>();
public void AddMapping(Type type, object associatedSource)
{
_typeToAssociateDictionary.TryAdd(type, associatedSource);
_associateToType.TryAdd(associatedSource, type);
}
public Type GetTypeSource(object associatedSource)
{
Type typeSource;
_associateToType.TryGetValue(associatedSource, out typeSource);
return typeSource;
}
public object GetAssociatedSource(Type typeSource)
{
object associatedSource;
_typeToAssociateDictionary.TryGetValue(typeSource, out associatedSource);
return associatedSource;
}
}
Enum with pages:
public enum NavigationPageSource
{
Page1,
Page2
}
App.cs
ファイル:
public class App : Application
{
public App()
{
var startPage = new Page1();
InitializeNavigation(startPage);
MainPage = new NavigationPage(startPage);
}
#region Sample of navigation initialization
private void InitializeNavigation(Page startPage)
{
var mapper = new SuperMapper();
mapper.AddMapping(typeof(Page1), NavigationPageSource.Page1);
mapper.AddMapping(typeof(Page2), NavigationPageSource.Page2);
var navigationService = DependencyService.Get<IViewNavigationService>();
navigationService.Initialize(startPage.Navigation, mapper);
}
#endregion
}
mapperでは、enum値を持ついくつかのページのタイプを関連付けました。
IViewNavigationService
実装:
[assembly: Dependency(typeof(ViewNavigationService))]
namespace SuperForms.Core.ViewNavigation
{
public class ViewNavigationService : IViewNavigationService
{
private INavigation _navigation;
private SuperMapper _navigationMapper;
public void Initialize(INavigation navigation, SuperMapper navigationMapper)
{
_navigation = navigation;
_navigationMapper = navigationMapper;
}
public async Task NavigateToAsync(object navigationSource, object parameter = null)
{
CheckIsInitialized();
var type = _navigationMapper.GetTypeSource(navigationSource);
if (type == null)
{
throw new InvalidOperationException(
"Can't find associated type for " + navigationSource.ToString());
}
ConstructorInfo constructor;
object[] parameters;
if (parameter == null)
{
constructor = type.GetTypeInfo()
.DeclaredConstructors
.FirstOrDefault(c => !c.GetParameters().Any());
parameters = new object[] { };
}
else
{
constructor = type.GetTypeInfo()
.DeclaredConstructors
.FirstOrDefault(c =>
{
var p = c.GetParameters();
return p.Count() == 1 &&
p[0].ParameterType == parameter.GetType();
});
parameters = new[] { parameter };
}
if (constructor == null)
{
throw new InvalidOperationException(
"No suitable constructor found for page " + navigationSource.ToString());
}
var page = constructor.Invoke(parameters) as Page;
await _navigation.PushAsync(page);
}
public async Task GoBackAsync()
{
CheckIsInitialized();
await _navigation.PopAsync();
}
private void CheckIsInitialized()
{
if (_navigation == null || _navigationMapper == null)
throw new NullReferenceException("Call Initialize method first.");
}
}
}
ユーザーがナビゲートしたいと思うページのタイプを取得し、それをリフレクションを使用してインスタンスとして作成します。
そして、私はビューモデル上でナビゲーションサービスを使うことができました:
var navigationService = DependencyService.Get<IViewNavigationService>();
await navigationService.NavigateToAsync(NavigationPageSource.Page2, "hello from Page1");
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow