带有EF核心的MVVM-作为命令参数的新实体,在视图模型中具有绑定属性



在深入研究Xamarin.Forms中的MVVM模式后,我将所有ViewModel函数封装到命令中,并从页面中的XAML调用它们。此外,我希望通过我的命令确保可测试性,所以我将依赖项作为命令参数传递。

我有一个页面,可以在其中创建一个新实体并将其添加到ef核心数据库中。

在用户将所有需要的值填充到组件中,从而设置ViewModel属性,并单击页面按钮后,应将实体添加到数据库中。

我的代码代表所描述的行为:

约会ViewModel.cs:

public class AppointmentViewModel : INotifyPropertyChanged
{
// Bound properties
public string Title { get; set; }
public DateTime Date { get; set; }
// Command to add new appointment
public ICommand AddAppointmentCommand { get; }
// The appointment entity which will be passed as a command parameter
public Appointment BoundAppointment => new Appointment(Title, Date);
AppointmentViewModel()
{
AddAppointmentCommand = new Command<Appointment>(async a => await AddAppointment(a));
}
public async Task AddAppointment(Appointment appointment)
{
// Code to add an appointment to the database through Entity Framework core
}
}

约会页面.xaml:

<Button Command="{Binding AddAppointmentCommand}" CommandParameter="{Binding BoundAppointment}"/>

我目前面临的问题是,属性BoundAppointment仅在打开页面时初始化,因此用户没有提供任何值。

因此,当执行命令时,创建的实体没有用户提供的值。(标题和日期仍有默认值(

我想将实体作为命令参数传递,但要使用提供的所有值。遗憾的是,我没有找到解决方案,这可以确保我的命令的可测试性,例如在单元测试中。

因此,当执行命令时,创建的实体没有用户提供的值。(标题和日期仍有默认值(

从您的代码中,您已经实现了INotifyPropertyChanged,但您没有实现viewmodel的每个属性的所有setter规则。您可以尝试根据以下代码修改您的代码。

public class AppointmentViewModel : INotifyPropertyChanged
{
// Bound properties
private string _Title;
public string Title
{
get { return _Title; }
set
{
_Title = value;
RaisePropertyChanged("Title");
}
}
private DateTime _Date;
public DateTime Date
{
get { return _Date; }
set
{
_Date = value;
RaisePropertyChanged("Date");
}
}
// Command to add new appointment
public ICommand AddAppointmentCommand { get; }
// The appointment entity which will be passed as a command parameter
private Appointment _BoundAppointment;
public Appointment BoundAppointment
{
get { return _BoundAppointment; }
set
{
_BoundAppointment = new Appointment(Title, Date);
RaisePropertyChanged("BoundAppointment");
}
}
AppointmentViewModel()
{
AddAppointmentCommand = new Command<Appointment>(async a => await AddAppointment(a));
}
public async Task AddAppointment(Appointment appointment)
{
// Code to add an appointment to the database through Entity Framework core
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

更新:

当标题和日期值更改时,您可以更新BoundAppointment

private string _Title;
public string Title
{
get { return _Title; }
set
{
_Title = value;
RaisePropertyChanged("Title");
BoundAppointment = new Appointment(Title, Date);
}
}
private DateTime _Date;
public DateTime Date
{
get { return _Date; }
set
{
_Date = value;
RaisePropertyChanged("Date");
BoundAppointment = new Appointment(Title, Date);
}
}

最新更新