BindableProperty стреляет только один раз - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть представление содержимого с 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();
    }
}

1 Ответ

1 голос
/ 10 апреля 2020
public static readonly BindableProperty AppointmentsDataProperty = BindableProperty.Create(nameof(AppointmentsData), typeof(CalendarControlModel), typeof(CalendarControlModel), new CalendarControlModel(),
        propertyChanged: (bindableObject, oldValue, newValue) =>
        {
            if (bindableObject is Calendar view)
            {
                view.AppointmentsData = (CalendarControlModel)newValue;
            }
        });

nameof (AppointmentsData): Указывает имя свойства, в котором хранится информация.

typeof (CalendarControlModel): Это тип свойства.

typeof (CalendarControlModel): Это тип класса, в котором находится свойство.

new CalendarControlModel (): Это просто значение по умолчанию.

Кажется, что вы установили неправильное значение третьего свойства

Кроме того, вы должны установить пользовательский интерфейс непосредственно в PropertyChanged, в противном случае вам нужно установить режим привязки: TwoWay

Так что улучшите ваш код, как показано ниже

public static readonly BindableProperty AppointmentsDataProperty = BindableProperty.Create(nameof(AppointmentsData), typeof(CalendarControlModel), typeof(Calendar), new CalendarControlModel(),BindingMode.OneWay,
            propertyChanged: (bindableObject, oldValue, newValue) =>
            {
                if (bindableObject is Calendar view)
                {
                   var model = newValue as CalendarControlModel;

                    var label = new Label { Text = $"{model.Hour}:{model.Minute}", HorizontalTextAlignment = TextAlignment.Center, FontSize = 32 };

                    view.MainScrollView.Content = label;



                }
            });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...