带有 EF Core 的 MVVM - 新实体作为命令参数,在视图模型中具有绑定属性
MVVM with EF Core - New entity as command parameter with bound properties in viewmodel
在 Xamarin.Forms 中深入研究了 MVVM 模式后,我将所有 ViewModel 函数包装到命令中,并从页面中的 XAML 调用它们。此外,我想通过我的命令确保可测试性,所以我将依赖项作为命令参数传递。
我有一个页面,可以在其中创建新实体并将其添加到 ef 核心数据库。
在用户将所有需要的值填入组件并设置 ViewModel 属性并单击页面按钮后,应将实体添加到数据库中。
代表所描述行为的我的代码:
AppointmentViewModel.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
}
}
AppointmentPage.xaml:
<Button Command="{Binding AddAppointmentCommand}" CommandParameter="{Binding BoundAppointment}"/>
我目前面临的问题是 属性 BoundAppointment
只在页面打开时初始化,因此用户没有提供任何值。
所以当命令执行时,创建的实体没有user-supplied的值。 (标题和日期仍然是默认值)
我想将我的实体作为命令参数传递,但包含所有提供的值。
可悲的是,我没有找到解决方案,这可以确保我的命令的可测试性,例如。在单元测试中。
So when the command is executed, the created entity hasn't the values the user-supplied. (The Title and Date still have their default values)
根据您的代码,您已经实现了 INotifyPropertyChanged,但是您没有实现每个 属性 视图模型的所有 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));
}
}
}
更新:
当 Title 和 Date 值更改时,您可以更新 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);
}
}
在 Xamarin.Forms 中深入研究了 MVVM 模式后,我将所有 ViewModel 函数包装到命令中,并从页面中的 XAML 调用它们。此外,我想通过我的命令确保可测试性,所以我将依赖项作为命令参数传递。
我有一个页面,可以在其中创建新实体并将其添加到 ef 核心数据库。
在用户将所有需要的值填入组件并设置 ViewModel 属性并单击页面按钮后,应将实体添加到数据库中。
代表所描述行为的我的代码:
AppointmentViewModel.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
}
}
AppointmentPage.xaml:
<Button Command="{Binding AddAppointmentCommand}" CommandParameter="{Binding BoundAppointment}"/>
我目前面临的问题是 属性 BoundAppointment
只在页面打开时初始化,因此用户没有提供任何值。
所以当命令执行时,创建的实体没有user-supplied的值。 (标题和日期仍然是默认值)
我想将我的实体作为命令参数传递,但包含所有提供的值。 可悲的是,我没有找到解决方案,这可以确保我的命令的可测试性,例如。在单元测试中。
So when the command is executed, the created entity hasn't the values the user-supplied. (The Title and Date still have their default values)
根据您的代码,您已经实现了 INotifyPropertyChanged,但是您没有实现每个 属性 视图模型的所有 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));
}
}
}
更新:
当 Title 和 Date 值更改时,您可以更新 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);
}
}