C# 使用EFCore重用MVVM模式上的视图

C# 使用EFCore重用MVVM模式上的视图,c#,wpf,mvvm,entity-framework-core,C#,Wpf,Mvvm,Entity Framework Core,我正在使用EF核心和MVVM模式,我不确定如何继续创建“可重用”视图 我有一个带有菜单条的视图,菜单条上有常用的操作(CRUD和过滤),还有一个将通过EF Core填充的DataGrid。我有一堆不同的模型(所有这些模型都继承了一个简单的基本模型类,带有一个intid属性),我需要显示我的数据 现在,根据DRY的说法,由于视图实际上是相同的,我不应该为每个模型创建不同的视图,只需要创建一个通用视图并相应地填充它。另外,我在这里读到了viewmodels通常是不可重用的,所以我需要为每个模型使用一

我正在使用EF核心和MVVM模式,我不确定如何继续创建“可重用”视图

我有一个带有菜单条的视图,菜单条上有常用的操作(CRUD和过滤),还有一个将通过EF Core填充的
DataGrid
。我有一堆不同的模型(所有这些模型都继承了一个简单的基本模型类,带有一个
intid
属性),我需要显示我的数据

现在,根据DRY的说法,由于视图实际上是相同的,我不应该为每个模型创建不同的视图,只需要创建一个通用视图并相应地填充它。另外,我在这里读到了viewmodels通常是不可重用的,所以我需要为每个模型使用一个viewmodel。这是我的问题

在创建视图时,我学到了以下模式:

public class StockView : Window
{
    private StockViewModel _viewModel;

    public StockView(StockViewModel viewModel)
    {
        InitializeComponent();
        _viewModel = viewModel ?? new StockViewModel();
        DataContext = _viewModel;
    }
}
然而,这意味着这个视图只接受
StockViewModel
,所以我不能重用它。我已经尝试为所有要继承的viewmodels创建一个抽象viewmodel库,并创建了通用视图

public class GenericView : Window
{
    private ViewModelBase _viewModel;

    public GenericView(ViewModelBase viewModel)
    {
        InitializeComponent();
        _viewModel = viewModel ?? new ViewModelBase();
        DataContext = _viewModel;
    }
}
但是现在,我将无法访问任何可以异步获取数据的viewmodel方法。异步抽象方法是不允许的,我尝试创建一个方法,该方法将创建一个服务类,该服务类将返回我的数据,但我也不能使用它:

public class StockService
{
    private MyDbContext _context = new MyDbContextFactory().CreateContext();
    
    public async Task<List<Stock>>GetStocksAsync()
    {
        return await _context.STOCKs.Select(x=>x).ToListAsync();
    }
}
公共类股票服务
{
私有MyDbContext_context=new MyDbContextFactory().CreateContext();
公共异步任务GetStocksAsync()
{
return wait_context.STOCKs.Select(x=>x.tolistSync();
}
}
公共抽象类ViewModelBase
{
公共摘要列表GetAllData();
}
公共类StockViewModel:ViewModelBase
{
公共覆盖列表GetAll()
{
var stockServ=new StockService();
返回stockServ.GetStocksAsync().Result//
不允许使用异步抽象方法

否,但
async
是一个实现细节。Abstract类或接口仍然可以定义一个方法,该方法返回一个
任务,然后您可以异步实现该任务:

public abstract class BaseViewModel<T>
{
    public abstract Task<IEnumerable<T>> GetItems();
}

public class StockViewModel : BaseViewModel<Stock>
{
    public override async Task<IEnumerable<Stock>> GetItems()
    {
        await ...
        return ...
    }
}
公共抽象类BaseViewModel
{
公共抽象任务GetItems();
}
公共类StockViewModel:BaseViewModel
{
公共重写异步任务GetItems()
{
等待。。。
返回。。。
}
}
不允许使用异步抽象方法

否,但
async
是一个实现细节。Abstract类或接口仍然可以定义一个方法,该方法返回一个
任务,然后您可以异步实现该任务:

public abstract class BaseViewModel<T>
{
    public abstract Task<IEnumerable<T>> GetItems();
}

public class StockViewModel : BaseViewModel<Stock>
{
    public override async Task<IEnumerable<Stock>> GetItems()
    {
        await ...
        return ...
    }
}
公共抽象类BaseViewModel
{
公共抽象任务GetItems();
}
公共类StockViewModel:BaseViewModel
{
公共重写异步任务GetItems()
{
等待。。。
返回。。。
}
}

谁教你的?改用数据模板。无论是谁,他们在WinForms思维定势中在窗口中创建Vm属性就像创建另一个DataContext,这都没有意义。谁教你的?改用数据模板。无论是谁,他们在WinForms思维定势中在窗口中创建Vm属性就像crea一样设置另一个DataContext没有任何意义。好吧,但是我的通用视图将是
公共标准列表视图(ViewModelBase viewModel)
。如何为股票模型实例化新视图?
新标准列表视图(新StockViewModel());
无效取决于您通常如何实例化视图和视图模型,但类似于
newview(){DataContext=anyViewModel}的东西如何
?不需要在视图中使用依赖项注入。这就解决了问题。我没有注入viewmodel,而是在实例化过程中设置它。现在,我所要做的就是公开一些从viewmodel库继承的常用属性/方法,它就行了。谢谢!!!好了,现在出现了另一个问题…我无法调用任何方法inherit由于我不能将
StockViewModel
向上转换到
ViewModelBase
所以我想在实例化上设置两个属性,DataContext本身和DataContext应该期望的实体类型类型。我想这是可行的。好吧,但是我的通用视图应该是
public StandardListView(ViewModelBase viewModel)
。如何实例化股票模型的新视图?
新标准列表视图(new StockViewModel());
无效取决于您通常如何实例化视图和视图模型,但类似于
新视图(){DataContext=anyViewModel}的东西如何
?不需要在视图中使用依赖项注入。这就解决了问题。我没有注入viewmodel,而是在实例化过程中设置它。现在,我所要做的就是公开一些从viewmodel库继承的常用属性/方法,它就行了。谢谢!!!好了,现在出现了另一个问题…我无法调用任何方法inherit由于我无法将
StockViewModel
向上转换到
ViewModelBase
,所以我想在实例化上设置两个属性,DataContext本身和DataContext应该期望的实体类型类型。我认为这会起作用。
public abstract class BaseViewModel<T>
{
    public abstract Task<IEnumerable<T>> GetItems();
}

public class StockViewModel : BaseViewModel<Stock>
{
    public override async Task<IEnumerable<Stock>> GetItems()
    {
        await ...
        return ...
    }
}