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