【发布时间】:2016-06-23 14:43:06
【问题描述】:
我在 Visual Studio 2015 中使用 MVVM Light 来构建 WPF 应用程序。代码中有一种方法在代码中重复了 4 次,但略有变化;唯一的区别是被修改的ObservableCollection的类型和数据服务层调用的方法。
这是方法,它返回一个StatusViewModel对象的ObservableCollection,用于填充ComboBox; StatusVm 用于绑定到ComboBox 的SelectedItem,设置为集合中的第一项并且为“空白”:
private async Task<ObservableCollection<StatusViewModel>> GetStatuses()
{
var result = new ObservableCollection<StatusViewModel>();
var blank = new StatusViewModel
{
StatusId = -1,
Status = null,
Description = null,
IsActive = false,
CreatedDate = DateTime.Now
};
result.Add(blank);
var dataService = new MyDataService();
foreach (var c in await dataService.GetStatuses())
result.Add(c);
StatusVm =
result.SingleOrDefault(c => c.StatusId.Equals(-1));
return result;
}
这是StatusVm 的私有字段和公共属性:
private StatusViewModel _statusVm;
public StatusViewModel StatusVm
{
get { return _statusVm; }
set
{
if (Equals(value, _statusVm)) return;
_statusVm = value;
RaisePropertyChanged();
}
}
现在想象上面的内容再重复 3 次,还有 3 种 VM 类型!如何使GetStatuses() 成为可以采用不同视图模型类型并在数据服务上调用适当方法的方法?谢谢。
更新:下面是另一种类型的属性和方法:
private MroViewModel_mroVm;
public MroViewModel MroVm
{
get { return _mroVm; }
set
{
if (Equals(value, _mroVm)) return;
_mroVm = value;
RaisePropertyChanged();
}
}
private async Task<ObservableCollection<MroViewModel>> GetMro()
{
var result = new ObservableCollection<MroViewModel>();
var blank = new MroViewModel
{
StatusId = -1,
Status = null,
Description = null,
IsActive = false,
CreatedDate = DateTime.Now
};
result.Add(blank);
var dataService = new MyDataService();
foreach (var c in await dataService.GetMro())
result.Add(c);
MroVm =
result.SingleOrDefault(c => c.StatusId.Equals(-1));
return result;
}
【问题讨论】:
-
泛化
GetStatuses()的两个问题是blank的初始化和对web方法GetStatuses()的调用。前者我会通过要求视图模型适当地初始化来处理,或者如果这不切实际,则通过要求它们实现一个返回blank实例的接口来处理。然后可能要求调用者传入一个调用 web 方法的 lambda,或者要求视图模型提供一个CallWebMethod()方法。或者将其添加到我上面提到的界面中。称它为IWebMethodRetrievable或类似名称。界面的想法在我心中成长。 -
如果所有类型都具有相同的属性,那么通用方法 lile private async Task
> GetStatuses(T t) 怎么样? -
你能发布其他方法吗?
-
@Alex 实际上 lambda 也需要异步,不是吗。这越来越丑了。让我摆弄一下。
-
@Alex 你知道吗,我也错过了
StatusVm初始化部分。一旦你排除了所有不能通用的东西,剩下的就不多了。我认为这实际上是 copy'n'paste(或 sn-p)是最不难看的选择的情况之一。