Caliburn.Micro 3.0(和Caliburn.Micro.Xamarin.Forms)是否實現了在Xamarin.Forms中模擬/支持Navigation.PushModalAsync
的功能?Caliburn.Micro 3.0相當於Xamarin.Forms Navigation.PushModalAsync
1
A
回答
6
不是,它不是內置的,但很容易增強它。通常,MvvM框架由ViewModels進行導航。 Caliburn正在遵循這種模式。所以它需要某種導航服務。這個導航服務負責爲ViewModel創建視圖並調用視圖框架(在我們的例子中是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使得很多函數都是私有的,所以我們必須將它們複製到我們的繼承版本中。
在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);
}
}
該方法返回一個ModalNavigateHelper
,簡化了我們的導航服務的使用(類似於卡利的NavigateHelper
)。這幾乎是一個副本,但對於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
班正在登記NavigationPageAdapter
INavigationService
作爲PrepareViewFirst
中的單身人士。我們有如下
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);
}
}
我們註冊我們的導航服務INavigationService
和IModalNavigationService
去改變它。
正如您在評論中看到的那樣,您必須實現自己調用PopModalAsync
的關閉函數。
相關問題
- 1. 我如何使用「DisplayAlert」使用Caliburn.Micro 3.0和Xamarin.Forms
- 2. 相當於FrameLayout的Xamarin.Forms佈局
- 3. Caliburn.Micro Xamarin.Forms ViewModel沒有初始化
- 4. WP7相當於EmptyDataTemplate?
- 5. Xamarin.Forms:相當於CSS:最後一種類型的選擇器
- 6. WinPhone 8.1項目與Xamarin.Forms和Caliburn.Micro failes創建視圖
- 7. NHibernate 3.0 QueryOver相當於Nhibernate中的FetchMany Linq
- 8. .format相當於
- 9. 相當於transaction.transactionReceipt.bytes
- 10. HQL'parsename'相當於
- 11. 相當於WeakHashMap?
- 12. wtol相當於#
- 13. 相當於JDIC?
- 14. 相當於SparkSQL
- 15. Android:getElementsByTagName相當於?
- 16. Fortran相當於
- 17. drupalPost()相當於
- 18. 相當於waitUntilAllOperationsAreFinished
- 19. 相當於
- 20. 相當於AWS
- 21. $ dialog.messageBox相當於
- 22. Linq相當於
- 23. 相當於@encode
- 24. 相當於C#
- 25. 訪問Xamarin.Forms中的相機
- 26. Caliburn.Micro和ORMs(NHibernate)
- 27. Java等於()相當於PHP
- 28. Xamarin.Forms UnhandledException當做請求時
- 29. callgrind相當於java?
- 30. ToolStripContainer相當於AutoScrollMinSize