Caliburn.Micro 3.0(およびCaliburn.Micro.Xamarin.Forms)は、Xamarin.FormsでNavigation.PushModalAsync
を模倣/サポートする機能を実装していますか?Caliburn.Micro 3.0がXamarin.Forms Navigation.PushModalAsyncに相当します。
答えて
いいえ、それはビルドではありませんが、それを強化するのは簡単です。通常、MvvMフレームワークはViewModelでナビゲートしています。キャリバーンはこのパターンに従っています。だから、ある種のナビゲーションサービスが必要です。このナビゲーションサービスは、ViewModelsのビューを作成し、ビューフレームワーク(ここではXamarin.Froms)固有のナビゲーション関数を呼び出します。 NavigationPageAdapter
は私たちが探しているものです。さて、それを強化しよう。
public interface IModalNavigationService : INavigationService
{
Task NavigateModalToViewModelAsync<TViewModel>(object parameter = null, bool animated = true);
// TODO: add more functions for closing
}
public class ModalNavigationPageAdapter : NavigationPageAdapter, IModalNavigationService
{
private readonly NavigationPage _navigationPage;
public ModalNavigationPageAdapter(NavigationPage navigationPage) : base(navigationPage)
{
_navigationPage = navigationPage;
}
public async Task NavigateModalToViewModelAsync<TViewModel>(object parameter = null, bool animated = true)
{
var view = ViewLocator.LocateForModelType(typeof(TViewModel), null, null);
await PushModalAsync(view, parameter, animated);
}
private Task PushModalAsync(Element view, object parameter, bool animated)
{
var page = view as Page;
if (page == null)
throw new NotSupportedException(String.Format("{0} does not inherit from {1}.", view.GetType(), typeof(Page)));
var viewModel = ViewModelLocator.LocateForView(view);
if (viewModel != null)
{
TryInjectParameters(viewModel, parameter);
ViewModelBinder.Bind(viewModel, view, null);
}
page.Appearing += (s, e) => ActivateView(page);
page.Disappearing += (s, e) => DeactivateView(page);
return _navigationPage.Navigation.PushModalAsync(page, animated);
}
private static void DeactivateView(BindableObject view)
{
if (view == null)
return;
var deactivate = view.BindingContext as IDeactivate;
if (deactivate != null)
{
deactivate.Deactivate(false);
}
}
private static void ActivateView(BindableObject view)
{
if (view == null)
return;
var activator = view.BindingContext as IActivate;
if (activator != null)
{
activator.Activate();
}
}
}
私達はちょうどINavigationService
を拡張し、私たちのModalNavigationPageAdapter
でそれを実装するインターフェイスIModalNavigationService
を宣言しました。残念ながら、Caliburnは多くの機能をプライベートにしていますので、継承バージョンにコピーする必要があります。
キャリバーンでは、navigationservice.For<VM>().Navigate()
でナビゲートできます。私たちはこのスタイルに従いたいので、拡張メソッドで行うのはnavigationservice.ModalFor<VM>().Navigate()
のようなものを実装する必要があります。
public static class ModalNavigationExtensions
{
public static ModalNavigateHelper<TViewModel> ModalFor<TViewModel>(this IModalNavigationService navigationService)
{
return new ModalNavigateHelper<TViewModel>().AttachTo(navigationService);
}
}
この方法は、(カリバーンのNavigateHelper
に似ています)私たちのナビゲーションサービスの利用を簡素化ModalNavigateHelper
を返します。それはほぼコピーですが、IModalNavigationService
です。
public class ModalNavigateHelper<TViewModel>
{
readonly Dictionary<string, object> parameters = new Dictionary<string, object>();
IModalNavigationService navigationService;
public ModalNavigateHelper<TViewModel> WithParam<TValue>(Expression<Func<TViewModel, TValue>> property, TValue value)
{
if (value is ValueType || !ReferenceEquals(null, value))
{
parameters[property.GetMemberInfo().Name] = value;
}
return this;
}
public ModalNavigateHelper<TViewModel> AttachTo(IModalNavigationService navigationService)
{
this.navigationService = navigationService;
return this;
}
public void Navigate(bool animated = true)
{
if (navigationService == null)
{
throw new InvalidOperationException("Cannot navigate without attaching an INavigationService. Call AttachTo first.");
}
navigationService.NavigateModalToViewModelAsync<TViewModel>(parameters, animated);
}
}
最後に、私たちは古いサービスの代わりに光っている新しいナビゲーションサービスを使用する必要があります。 App
クラスは、にシングルトンとしてINavigationService
のNavigationPageAdapter
を登録しています。私たちは、私たちはINavigationService
とIModalNavigationService
のための私達のナビゲーションサービスを登録している
public class App : FormsApplication
{
private readonly SimpleContainer container;
public App(SimpleContainer container)
{
this.container = container;
container
.PerRequest<LoginViewModel>()
.PerRequest<FeaturesViewModel>();
Initialize();
DisplayRootView<LoginView>();
}
protected override void PrepareViewFirst(NavigationPage navigationPage)
{
var navigationService = new ModalNavigationPageAdapter(navigationPage);
container.Instance<INavigationService>(navigationService);
container.Instance<IModalNavigationService>(navigationService);
}
}
を次のように変更する必要があります。
コメントに見られるように、自分でPopModalAsync
を呼び出すclose関数を実装する必要があります。
- 1. Caliburn.Micro 2.0/3.0 Bind.Model replacement
- 2. Firebase 3.0で$ requireAuthに相当する
- 3. C#3.0タプル相当(男性用)
- 4. XQuery 3.0相当のグループby xquery 1.0 version
- 5. Caliburn.Micro 3.0とXamarin.Formsを使って "DisplayAlert"を使うにはどうすればいいですか
- 6. layoutSubviewsに相当するXamarin.Formsとは何ですか?
- 7. Caliburn.Micro Xamarin.Forms ViewModelが初期化されない
- 8. Android 3.0のFragmentTransaction attach/detachに相当する
- 9. NHibernate 3.0 Nhibernate LinqのFetchManyに相当するQueryOver
- 10. Xamarin.Forms Caliburn.Micro - 複数のビューを1つのViewModelに関連付けます
- 11. luaのリターンに相当しますか?
- 12. バッチスクリプトのcutコマンドに相当します
- 13. Goでsetdefaultに相当しますか?
- 14. Typescriptパッケージスコープに相当しますか?
- 15. SprintfはMathematicaに相当しますか?
- 16. ウェブアプリケーションのapplication.doevents()に相当しますか?
- 17. マイクロフォーマットのDTDに相当しますか?
- 18. .NET内のjava.net.URLConnectionに相当します。
- 19. .NETはGetLastInputInfoに相当しますか?
- 20. jqueryのonmoveイベントに相当します。
- 21. QtのGtkSpinnerに相当しますか?
- 22. Pythonのdecode( 'hex')に相当します。
- 23. .NETのGWTに相当しますか?
- 24. Symfony2はbefore_filterに相当しますか?
- 25. Domo - Tableauパラメータに相当します。
- 26. JavaのC++ map.lower_boundに相当します。
- 27. Javaのmemcmp()に相当しますか?
- 28. JavaのC++バリデーションテンプレートに相当します。
- 29. cmd 'call'コマンドに相当しますか?
- 30. アプリエクステンションのUIApplication.shared.preferredContentSizeCategoryに相当します。