使用泛型,我有一个基类视图模型 - (MyBaseViewModel
<T>
),它实现了社区工具包 RelayCommand。这是由支持数据输入用户控件的 ViewModel - MyDataInputControlViewModel 继承的:MyBaseViewModel<MyCustomType>
。中继命令需要使用来自用户控件的数据更新数据库。如何将 <MyCustomType
中的数据传递给 RelayCommand?
因此,我试图了解泛型和继承,并认为实现处理数据库 CRUD 的基本视图模型可以节省大量时间,为需要进入数据库的所有不同数据类型重复命令。最初的想法来自 xamlbrewer ,但这将中继命令保留在用户控制视图模型中,我可以这样做,但我想将它们放入基类中。
来自基类的代码
public abstract partial class ObservableNavigationAwareViewModelBase<T> : ObservableObject, INavigationAware
{
readonly DatabaseDAO _databaseDAO;
private T BaseNewItem;
public ObservableNavigationAwareViewModelBase(DatabaseDAO databaseDAO) { _databaseDAO = databaseDAO; }
[RelayCommand]
private void BaseAddNewRecord() { _databaseDAO.SaveNewRecord(BaseNewItem); }
来自用户控件视图模型的代码
public partial class AddNewTenantViewModel : ObservableNavigationAwareViewModelBase<Tenant>
{
DatabaseDAO _databaseDAO;
public string FirstName { get; set; }
public AddNewTenantViewModel(DatabaseDAO databaseDAO) : base (databaseDAO)
{_databaseDAO = databaseDAO;}
private void CreateNewTenant()
{ BaseNewItem = new Tenant() { FirstName = FirstName, }; }
租户模式
[Table("tenants")]
public partial class Tenant
{
public string FirstName { get; set; }
}
这是我正在使用的测试xaml
<TextBox Text="{x:Bind ViewModel.FirstName, Mode=TwoWay}" Header="First Name" />
<Button Content="Add" Command="{x:Bind ViewModel.BaseAddNewRecordCommand}" />
调用基类中的命令很好,但我看不到如何从那里创建 BaseNewItem。 因此,据我所知,我可以创建 BaseNewItem 的唯一位置是在 UserControl ViewModel 中?我知道我可以访问基类和继承类中的 BaseNewItem,但无法从基类调用 CreateNewTenant。所以我的问题是“如何将 BaseNewItem 获取到要在命令中使用的 Base 类”。或者我完全错过了某个地方的重点?
您可以使用抽象方法:
public abstract partial class ViewModelBase<T> : ObservableObject
{
private readonly DatabaseDAO _databaseDAO = new();
abstract protected object CreateNewItem(string name);
[RelayCommand]
private void AddNewRecord(string name)
{
var record = CreateNewItem(name);
_databaseDAO.SaveNewRecord(record);
}
}
并覆盖它派生的视图模型:
public class TenantViewModel : ViewModelBase<Tenant>
{
protected override Tenant CreateNewItem(string name)
{
return new Tenant(name);
}
}
然后使用这样的命令:
<TextBox x:Name="NameTextBox" />
<Button
Command="{x:Bind TenantViewModel.AddNewRecordCommand}"
CommandParameter="{x:Bind NameTextBox.Text, Mode=OneWay}"
Content="Save Tenant" />