У меня есть представление содержимого с BindableProperty, которое привязывается к родительской ViewModel. При получении нового значения свойство, связанное с BindableProperty, запускает метод, который программно создает новый набор элементов управления в представлении содержимого. BindableProperty запускается только при установке BindingContext для родительского представления. Может кто-нибудь подскажите, пожалуйста, что я делаю не так?
РЕДАКТИРОВАТЬ
Похоже, что исправление третьего параметра в BindableProperty.Create
(от typeof(CalendarControlModel)
до typeof(Calendar)
и добавление BindingMode.TwoWay,
решает проблему.
Новый вопрос: Почему здесь необходимо двухстороннее связывание?
Код представления содержимого позади
public partial class Calendar
{
public static readonly BindableProperty AppointmentsDataProperty = BindableProperty.Create(nameof(AppointmentsData), typeof(CalendarControlModel), typeof(Calendar), new CalendarControlModel(),BindingMode.TwoWay
propertyChanged: (bindableObject, oldValue, newValue) =>
{
if (bindableObject is Calendar view)
{
view.AppointmentsData = (CalendarControlModel)newValue;
}
});
public CalendarControlModel AppointmentsData { get { return (CalendarControlModel)GetValue(AppointmentsDataProperty); } set { SetValue(AppointmentsDataProperty, value); PrepareAppointments(); } }
public Calendar()
{
InitializeComponent();
}
private void PrepareAppointments()
{
....
MainScrollView.Content = meetingsGrid;
}
Просмотр содержимого
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="NS.Controls.Calendar">
<ContentView.Content>
<ScrollView x:Name="MainScrollView">
</ScrollView>
</ContentView.Content>
</ContentView>
Просмотр модели
class CalendarPageViewModel : BaseViewModel
{
private DailyCalendarControlModel appointmentsData;
public ObservableCollection<PickerModel> AppointmentTypes { get; set; }
public DailyCalendarControlModel AppointmentsData
{
get => appointmentsData;
set => SetProperty(ref appointmentsData, value);
}
public PickerModel SelectedAppointmentType { get; set; }
public CalendarSummaryModel Summary { get; set; }
public ICommand SwitchDayCommand { get; set; }
public ICommand SwitchAppointmentType { get; set; }
public DailyCalendarPageViewModel()
{
SwitchDayCommand = new Command<DateTime>(date =>
{
if (date.Day % 2 == 1)
{
AppointmentsData = new DailyCalendarControlModel
{
Appointments = DataGenerators.GenerateAppointmentsList1(),
Schedule = DataGenerators.GenerateSchedule()
};
}
else
{
AppointmentsData = new DailyCalendarControlModel
{
Appointments = DataGenerators.GenerateAppointmentsList2(),
Schedule = DataGenerators.GenerateSchedule()
};
}
});
SwitchAppointmentType = new Command<int>(type =>
{
});
}
}
Просмотр родительской страницы
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:controls="clr-namespace:NS.Controls;assembly=NS"
mc:Ignorable="d"
x:Class="NS.Views.CalendarPage">
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<controls:PageHeader NextDayCommand="{Binding SwitchDayCommand}" PreviousDayCommand="{Binding SwitchDayCommand}" ChangedTypeCommand="{Binding SwitchAppointmentType}" />
<controls:Calendar x:Name="CalendarControl" AppointmentsData="{Binding AppointmentsData}" Grid.Row="1" />
<controls:CalendarSummary Summary="{Binding Summary}" Grid.Row="2" />
</Grid>
</ContentPage.Content>
</ContentPage>
Код родительской страницы за
public partial class CalendarPage : ContentPage
{
public CalendarPage()
{
InitializeComponent();
var appointmentTypes = EnumFactories.CreateFromEventType();
CalendarPageViewModel model = new CalendarPageViewModel
{
SelectedAppointmentType = appointmentTypes.FirstOrDefault(a => a.Id == (int)EventType.Consultation),
AppointmentTypes = appointmentTypes,
//SelectedDate = DateTime.Now.Date,
AppointmentsData = new CalendarControlModel {Appointments = DataGenerators.GenerateAppointmentsList(), Schedule = DataGenerators.GenerateSchedule() },
Summary = new CalendarSummaryModel
{
AppointmentsSummaries = $"Cabinet1",
TotalAppointments = "5",
TotalSum = "1"
}
};
BindingContext = model;
}
protected override void OnAppearing()
{
base.OnAppearing();
CalendarControl.ScrollToCurrentTime();
}
}