Mvvm BindableProperty只触发一次

Mvvm BindableProperty只触发一次,mvvm,xamarin.forms,Mvvm,Xamarin.forms,我有一个内容视图,它有一个绑定到父视图模型的BindableProperty。收到新值时,绑定到BindableProperty的属性会触发一个方法,该方法在内容视图中以编程方式创建一组新控件。只有在为父视图设置BindingContext时,才会激发BindingTableProperty。有人能告诉我我做错了什么吗 编辑 class CalendarPageViewModel : BaseViewModel { private DailyCalendarControlModel ap

我有一个内容视图,它有一个绑定到父视图模型的BindableProperty。收到新值时,绑定到BindableProperty的属性会触发一个方法,该方法在内容视图中以编程方式创建一组新控件。只有在为父视图设置BindingContext时,才会激发BindingTableProperty。有人能告诉我我做错了什么吗

编辑

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 =>
            {

            });
    }
}
似乎更正了
BindableProperty.Create
(从
typeof(CalendarControlModel)
typeof(Calendar)
,并添加了
BindingMode。双向,
解决了这个问题

新问题:为什么这里需要双向绑定

内容视图代码隐藏

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;
    }
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();
    }
}
内容视图

<?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>
<?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>
nameof(任命数据):提供存储信息的属性名称

typeof(CalendarControlModel):这是属性的类型

typeof(CalendarControlModel):这是属性所在类的类型

新建CalendarControlModel():这只是默认值

您似乎设置了第三个属性的错误值

此外,您应该直接在PropertyChanged中设置UI,否则需要将绑定模式设置为双向

所以,像下面这样改进代码

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;



                }
            });

我无法从您的代码中找到原因。您可以提供一个包含此问题的示例,以便我可以在我这边测试。@LucasZhang MSFT我将准备一个示例。我将把它放在哪里/发送它?感谢您的帮助。您可以将其发布到github上。@LucasZhang MSFT我在github上添加了一个示例项目。再次感谢!
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;



                }
            });