mvvmCross 的侧边菜单
SideMenu for mvvmCross
正在为 Xamarin.iOS
应用实现侧边菜单,但在控制台中收到警告:
mvx:Warning: 0.25 No sidemenu found. To use a sidemenu decorate the
viewcontroller class with the 'MvxPanelPresentationAttribute' class
and set the panel to 'Left' or 'Right'.
步骤
1) 为菜单创建基础 class(来自 sample)
public class BaseMenuViewController<T> : MvxViewController<T>, IMvxSidebarMenu where T : class, IMvxViewModel
{
public virtual UIImage MenuButtonImage => UIImage.FromBundle("burger");
public virtual bool AnimateMenu => true;
public virtual float DarkOverlayAlpha => 0;
public virtual bool HasDarkOverlay => false;
public virtual bool HasShadowing => true;
public virtual bool DisablePanGesture => false;
public virtual bool ReopenOnRotate => true;
private int MaxMenuWidth = 300;
private int MinSpaceRightOfTheMenu = 55;
public int MenuWidth => UserInterfaceIdiomIsPhone ?
int.Parse(UIScreen.MainScreen.Bounds.Width.ToString()) - MinSpaceRightOfTheMenu : MaxMenuWidth;
private bool UserInterfaceIdiomIsPhone
{
get { return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; }
}
public virtual void MenuWillOpen()
{
}
public virtual void MenuDidOpen()
{
}
public virtual void MenuWillClose()
{
}
public virtual void MenuDidClose()
{
}
}
2) 实现 VisibleView(第一个可见的)
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true)]
public partial class ContentViewController : MvxViewController<ContentViewModel>
{
public ContentViewController()
: base("ContentViewController", null)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
View.BackgroundColor = UIColor.Purple;
this.ViewModel.Show<MenuViewModel>();
}
}
3) 实施 MenuElementViewController(侧边菜单)
[Register("MenuViewController")]
[MvxSidebarPresentation(MvxPanelEnum.Left, MvxPanelHintType.PushPanel, false)]
public class MenuViewController : BaseMenuViewController<MenuViewModel>
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
this.View.BackgroundColor = UIColor.Red;
}
}
4) 在设置中为 SideMenu 添加演示者
protected override IMvxIosViewPresenter CreatePresenter()
{
return new MvxSidebarPresenter((MvxApplicationDelegate)ApplicationDelegate, Window);
}
预期行为
应该从点 1 看到带有汉堡按钮的控制器
实际行为
点 1 的控制器变得可见但没有汉堡按钮,
来自 point2 的控制器未初始化,
控制台中关于 class 错过装饰的警告,但如您所见,它们存在(警告也已弃用,需要更新 - check source code - searching done for correct type, but warning has old message)
配置
MvvmCross v 5.0.6
- MvvmCross
- MvvmCross.Core
- MvvmCross.Binding
- MvvmCross.iOS.Support
- MvvmCross.iOS.Support.XamarinSidebar
- MvvmCross.Platform
- 侧边栏导航
在查找错误时也看到 - 重新检查,看起来一切正常,但无法正常工作。
警告日志:
mvx:Diagnostic: 0.21 Setup: Secondary end
mvx:Diagnostic: 0.21 Showing ViewModel ContentViewModel
iOSNavigation:Diagnostic: 0.21 Navigate requested
mvx:Warning: 0.23 No sidemenu found. To use a sidemenu decorate the viewcontroller class with the 'MvxPanelPresentationAttribute' class and set the panel to 'Left' or 'Right'.
我还希望在调用 this.ViewModel.Show<MenuViewModel>();
时在 ViewDidload
中看到 MenuViewController
的断点停止,但它从未被触发,同时创建了此控制器的模型。
谁能告诉我做错了什么?
编辑
我能够设置 new empty project with sidebar 并且它按预期工作。但是相同的代码在我当前的项目中不起作用 - 我不知道为什么没有按预期读取装饰属性....
该跟踪是由 MvxSidebarViewController
中的这段代码触发的。
protected virtual void SetupSideMenu()
{
var leftSideMenu = ResolveSideMenu(MvxPanelEnum.Left);
var rightSideMenu = ResolveSideMenu(MvxPanelEnum.Right);
if (leftSideMenu == null && rightSideMenu == null)
{
Mvx.Trace(MvxTraceLevel.Warning, $"No sidemenu found. To use a sidemenu decorate the viewcontroller class with the 'MvxPanelPresentationAttribute' class and set the panel to 'Left' or 'Right'.");
AttachNavigationController();
return;
}
// ...
}
因此 Mvvmcross 无法解析标有您在上面使用的属性的 SideMenu 视图控制器。我建议删除所有 MvvmCross nugets 并删除 bin 和 obj 文件夹。
可能尝试向 MenuViewController
添加构造函数可能会有所帮助。
如果所有这些都失败了,我会尝试构建 classes 完全按照它们在测试项目中的样子,我注意到你的 ContentViewController
不是从基础 class 继承的就像在项目中一样。我知道这不应该真正相关,但我从侧边栏的实验中发现 classes 是 ViewControllers 和嵌套视图控制器的设置非常特别。
我完全放弃了 MvvmCross siderbar nuget,直接使用了 XamarinSidebar nuget,我使用 MvxSidebarViewController
作为创建我自己的实现的起点,我不是特别热衷于属性设置和我喜欢自己处理导航而不是使用 ShowViewModel
或新的导航系统。
希望对您有所帮助。
花2天时间找出原因——检测和解析装饰器属性的问题。
我有几个项目彼此共享代码库,并且由于某种原因
[MvxSidebarPresentation(MvxPanelEnum.Left, MvxPanelHintType.PushPanel, false)]
如果它放置在共享项目中但不在项目本身中,则不会被考虑在内。在同一时刻
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true)]
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true, MvxSplitViewBehaviour.Master)]
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.PushPanel, true, MvxSplitViewBehaviour.Detail)]
按预期工作。
解决方法 -> 在每个项目中应该使用它的子类共享 menuClass(MvxPanelEnum.Left
)。
不确定此问题是否与 mvvmCross 库或 Xamarin.
正在为 Xamarin.iOS
应用实现侧边菜单,但在控制台中收到警告:
mvx:Warning: 0.25 No sidemenu found. To use a sidemenu decorate the viewcontroller class with the 'MvxPanelPresentationAttribute' class and set the panel to 'Left' or 'Right'.
步骤
1) 为菜单创建基础 class(来自 sample)
public class BaseMenuViewController<T> : MvxViewController<T>, IMvxSidebarMenu where T : class, IMvxViewModel
{
public virtual UIImage MenuButtonImage => UIImage.FromBundle("burger");
public virtual bool AnimateMenu => true;
public virtual float DarkOverlayAlpha => 0;
public virtual bool HasDarkOverlay => false;
public virtual bool HasShadowing => true;
public virtual bool DisablePanGesture => false;
public virtual bool ReopenOnRotate => true;
private int MaxMenuWidth = 300;
private int MinSpaceRightOfTheMenu = 55;
public int MenuWidth => UserInterfaceIdiomIsPhone ?
int.Parse(UIScreen.MainScreen.Bounds.Width.ToString()) - MinSpaceRightOfTheMenu : MaxMenuWidth;
private bool UserInterfaceIdiomIsPhone
{
get { return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; }
}
public virtual void MenuWillOpen()
{
}
public virtual void MenuDidOpen()
{
}
public virtual void MenuWillClose()
{
}
public virtual void MenuDidClose()
{
}
}
2) 实现 VisibleView(第一个可见的)
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true)]
public partial class ContentViewController : MvxViewController<ContentViewModel>
{
public ContentViewController()
: base("ContentViewController", null)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
View.BackgroundColor = UIColor.Purple;
this.ViewModel.Show<MenuViewModel>();
}
}
3) 实施 MenuElementViewController(侧边菜单)
[Register("MenuViewController")]
[MvxSidebarPresentation(MvxPanelEnum.Left, MvxPanelHintType.PushPanel, false)]
public class MenuViewController : BaseMenuViewController<MenuViewModel>
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
this.View.BackgroundColor = UIColor.Red;
}
}
4) 在设置中为 SideMenu 添加演示者
protected override IMvxIosViewPresenter CreatePresenter()
{
return new MvxSidebarPresenter((MvxApplicationDelegate)ApplicationDelegate, Window);
}
预期行为
应该从点 1 看到带有汉堡按钮的控制器
实际行为
点 1 的控制器变得可见但没有汉堡按钮, 来自 point2 的控制器未初始化, 控制台中关于 class 错过装饰的警告,但如您所见,它们存在(警告也已弃用,需要更新 - check source code - searching done for correct type, but warning has old message)
配置
MvvmCross v 5.0.6
- MvvmCross
- MvvmCross.Core
- MvvmCross.Binding
- MvvmCross.iOS.Support
- MvvmCross.iOS.Support.XamarinSidebar
- MvvmCross.Platform
- 侧边栏导航
在查找错误时也看到
警告日志:
mvx:Diagnostic: 0.21 Setup: Secondary end
mvx:Diagnostic: 0.21 Showing ViewModel ContentViewModel iOSNavigation:Diagnostic: 0.21 Navigate requested
mvx:Warning: 0.23 No sidemenu found. To use a sidemenu decorate the viewcontroller class with the 'MvxPanelPresentationAttribute' class and set the panel to 'Left' or 'Right'.
我还希望在调用 this.ViewModel.Show<MenuViewModel>();
时在 ViewDidload
中看到 MenuViewController
的断点停止,但它从未被触发,同时创建了此控制器的模型。
谁能告诉我做错了什么?
编辑
我能够设置 new empty project with sidebar 并且它按预期工作。但是相同的代码在我当前的项目中不起作用 - 我不知道为什么没有按预期读取装饰属性....
该跟踪是由 MvxSidebarViewController
中的这段代码触发的。
protected virtual void SetupSideMenu()
{
var leftSideMenu = ResolveSideMenu(MvxPanelEnum.Left);
var rightSideMenu = ResolveSideMenu(MvxPanelEnum.Right);
if (leftSideMenu == null && rightSideMenu == null)
{
Mvx.Trace(MvxTraceLevel.Warning, $"No sidemenu found. To use a sidemenu decorate the viewcontroller class with the 'MvxPanelPresentationAttribute' class and set the panel to 'Left' or 'Right'.");
AttachNavigationController();
return;
}
// ...
}
因此 Mvvmcross 无法解析标有您在上面使用的属性的 SideMenu 视图控制器。我建议删除所有 MvvmCross nugets 并删除 bin 和 obj 文件夹。
可能尝试向 MenuViewController
添加构造函数可能会有所帮助。
如果所有这些都失败了,我会尝试构建 classes 完全按照它们在测试项目中的样子,我注意到你的 ContentViewController
不是从基础 class 继承的就像在项目中一样。我知道这不应该真正相关,但我从侧边栏的实验中发现 classes 是 ViewControllers 和嵌套视图控制器的设置非常特别。
我完全放弃了 MvvmCross siderbar nuget,直接使用了 XamarinSidebar nuget,我使用 MvxSidebarViewController
作为创建我自己的实现的起点,我不是特别热衷于属性设置和我喜欢自己处理导航而不是使用 ShowViewModel
或新的导航系统。
希望对您有所帮助。
花2天时间找出原因——检测和解析装饰器属性的问题。
我有几个项目彼此共享代码库,并且由于某种原因
[MvxSidebarPresentation(MvxPanelEnum.Left, MvxPanelHintType.PushPanel, false)]
如果它放置在共享项目中但不在项目本身中,则不会被考虑在内。在同一时刻
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true)]
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.ResetRoot, true, MvxSplitViewBehaviour.Master)]
[MvxSidebarPresentation(MvxPanelEnum.Center, MvxPanelHintType.PushPanel, true, MvxSplitViewBehaviour.Detail)]
按预期工作。
解决方法 -> 在每个项目中应该使用它的子类共享 menuClass(MvxPanelEnum.Left
)。
不确定此问题是否与 mvvmCross 库或 Xamarin.