我正在VS 2019中使用Xamarin Forms 4.0创建一个跨平台应用程序。
我需要一个向上滑动菜单,其菜单选项根据日历选择中所点击的单元格日期而变化。我已经安装了SlideOverKit来尝试完成此任务。获取菜单本身是有效的,但是不能动态更改选项。
我应该如何进行?
正如我所说,我尝试传递日期,但是我也尝试将日期保存到SecureStorage并在SlideUpMenu的加载方法中请求字符串...我相信我可能会遇到“视图的生命周期” '问题。
在这里,我将选择的日期从内容页面传递到幻灯片菜单视图和包含数据的模型。
public partial class PublicCalendarPage : MenuContainerPage
{
private CalendarModel _calendarModel;
private bool _showDetails = true;
public PublicCalendarPage(CalendarModel calendarModel)
{
InitializeComponent();
Content.BackgroundColor = Color.White;
BindingContext = new PublicCalendarViewModel(this, new ApiService())
{
CalendarModel = GetCalendarModel(calendarModel)
};
_calendarModel = calendarModel;
SlideMenu = new ShowMealsView(new DateTime(), calendarModel.CalendarDays);
}
private CalendarModel GetCalendarModel(CalendarModel calendarModel)
{
//gets the model data via api call
}
private void Schedule_OnCellTapped(object sender, CellTappedEventArgs e)
{
SlideMenu = new ShowMealsView(e.Datetime, _calendarModel.CalendarDays);
ShowMenu();
}
}
下面是加载菜单的代码
public partial class ShowMealsView : SlideMenuView
{
private readonly List<CalendarDayModel> _calendarDays;
public ShowMealsView(DateTime eDatetime, List<CalendarDayModel> calendarDaysList)
{
InitializeComponent();
HeightRequest = 80;
IsFullScreen = true;
MenuOrientations = MenuOrientation.BottomToTop;
BackgroundColor = Color.LightGray;
BackgroundViewColor = Color.Transparent;
_calendarDays = calendarDaysList;
if (Device.RuntimePlatform == Device.Android)
this.HeightRequest += 50;
var layout = GetLayout(eDatetime);
Content = layout;
}
private Grid GetLayout(DateTime date)
{
var layout = new Grid();
// formats grid layout before the relevant code
var dinnerGrid = new Grid();
dinnerGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
dinnerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(10, GridUnitType.Absolute) });
dinnerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
var dinnerBox = new BoxView
{
VerticalOptions = LayoutOptions.Fill,
BackgroundColor = Color.FromHex("#f3d176")
};
dinnerGrid.Children.Add(dinnerBox, 0, 0);
//var selectedDate = SecureStorage.GetAsync("SelectedDate").Result;
var selectedDateTime = date;
var dinnerLabel = new Label
{
Text = "Provide Dinner",
TextColor = Color.Black,
HorizontalOptions = LayoutOptions.Center,
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center,
VerticalOptions = LayoutOptions.Center
};
if (_calendarDays.Any(x => x.ForDay == selectedDateTime.Date && x.Email != null))
{
dinnerLabel = new Label
{
Text = $"A DINNER EXISTS!",
TextColor = Color.Black,
HorizontalOptions = LayoutOptions.Center,
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center,
VerticalOptions = LayoutOptions.Center
};
}
dinnerGrid.Children.Add(dinnerLabel, 1, 0);
var table = new TableView
{
Root = new TableRoot { new TableSection { new ViewCell() { View = lunchGrid }, new ViewCell() { View = dinnerGrid } } },
Intent = TableIntent.Data
};
layout.Children.Add(table, 0, 0);
return layout;
}
}
初始加载返回“提供晚餐”
在内容页面上选择日期后,菜单选择应包括“晚餐存在!”
但是,即使调试显示DinnerLabel.Text可能等于“ A Dinner EXISTS”,屏幕上实际显示的还是“ Provide Dinner”
更新: 我转而使用ObservableCollection,将该集合用作ListView项源,因为我一直在阅读ListView会根据列表中的数据自动更新其视图。 (如果添加或删除了任何内容)
这不起作用,但是我愿意承认我可能做错了,因为我从未使用过ListViews ...
从本质上讲,我仍然只获得原始状态的视图,该视图仅显示“提供晚餐”;再次调试时,模型中分配的属性确实具有值“ A Dinner Exists!”。 ...因此使用不同的方法可获得相同的结果
答案 0 :(得分:1)
我认为这是SlideOverKit
的限制,您不能动态更改SlideMenu。
我下载了示例,并使用您的代码进行测试。我也遇到你同样的问题。
然后我在Github上发现了类似的问题here,作者推荐您使用use binding IsVisible to show different view in a single slide menu
。
后来,我发现与change SlideMenu dynamically
有关的另一个问题here,作者说:
嗯,它不能被添加,原因是OnAppearing会在之后被调用 OnElementChanged。如何在运行时更改MenuView中的内容? 对于ViewA来说,设置为IsVisible,对于ViewB则设置为不可见