我正在研究一个遵循MVVM模式的WPF应用程序。尽管将验证转移到服务中,我最终会得到一个运行多行代码的胖视图模型(在我的情况下接近1000行)。 我在这里添加了viewmodel的界面。我将一些集合暴露为组合并基于组合选择,我必须对其他组合执行验证/调用服务/应用过滤
public interface ISampleViewModel {
ObservableCollection<InstrumentDto> Collection1 { get; set; }
ObservableCollection<TenderViewConfigDetailViewModel> Collection2 { get; set; }
ObservableCollection<TenderViewConfigDetailViewModel> Collection3 { get; set; }
ObservableCollection<TenderViewConfigDetailViewModel> Collection4 { get; set; }
ObservableCollection<TenderViewConfigDetailViewModel> Collection5 { get; set; }
TenderViewConfigDetailViewModel SelectedViewConfigDetail { get; set; }
int SelectedTenderViewIndex { get; set; }
int SelectedInstrumentsViewIndex { get; set; }
SortableCollection<TenderViewToInstrumentViewModel> CurrentInstruments { get; set; }
TenderViewToInstrumentViewModel SelectedInstrumentForTenderView { get; set; }
InstrumentDto SelectedInstrument { get; set; }
bool IsAllInstrumentsFocused { get; set; }
ICommand ApplyChangesCommand { get; }
ICommand AddTenderPanelViewCommand { get; }
ICommand DeleteTenderPanelViewCommand { get; }
ICommand ModifyTenderViewVisiblityCommand { get; }
ICommand AddInstrumentsToPanelViewCommand { get; }
ICommand DeleteInstrumentsFromPanelViewCommand { get; }
ICommand MoveUpTenderListViewCommand { get; }
ICommand MoveDownTenderListViewCommand { get; }
ICommand MoveUpInstrumentsCommand { get; }
ICommand MoveDownInstrumentsCommand { get; }
bool IsValidModel { get; }
void PublishTenderViewConfigChanges(TenderViewConfigDetailViewModel viewModel,EventActionType actionType);
}
上述功能使我的viewmodel变得更加庞大。我该如何避免避免呢?我不能想到将功能分解为更小的控件,因为它们依赖于它们?我在这里错过了什么吗?
答案 0 :(得分:2)
如果您已存储在可以在单独的类中隔离的ViewModel
属性中,则最好将它们移到单独的Model
。大量属性非常重要ViewModel
,对于您应创建Model
的每种类型的属性。虽然在这种情况下存在一些争论,但我认为如果在ViewModel
中将链接到多个Models
,则没有任何错误。在这个主题上你可以看到这个答案:
In MVVM, is every ViewModel coupled to just one Model?
使用单独模型的示例:
<强> Model
强>
public class MainMenuModel : NotificationObject // Here also implemented INotifyPropertyChanged interface
{
private bool _buttonIsEnabled = true;
public bool ButtonIsEnabled
{
get
{
return _buttonIsEnabled;
}
set
{
_buttonIsEnabled = value;
NotifyPropertyChanged("ButtonIsEnabled");
}
}
}
<强> ViewModel
强>
public class MainMenuViewModel
{
private MainMenuModel _mainMenuModel = null;
public MainMenuModel MainMenuModel
{
get
{
return _mainMenuModel;
}
set
{
_mainMenuModel = value;
}
}
...
public MainMenuViewModel()
{
MainMenuModel = new MainMenuModel();
}
}
<强> View
强>
<Button IsEnabled="{Binding Path=MainMenuModel.ButtonIsEnabled}" ... />
唯一可以留在ViewModel
,命令和IDataErrorInfo
接口实现的一面,尽管IDataErrorInfo
的实现也可以移到Model
的一边{1}}。
此外,如果Command的实现占用大量空间,您可以创建可以称为Helper
的单独函数/过程并放置在合适的类中。接下来,在Command中没有编写整个实现,有必要参考这个方法。
例如:
private ICommand _findCommand = null;
public ICommand FindCommand
{
get
{
if (_findCommand == null)
{
_findCommand = new RelayCommand(param => this.Find(), null);
}
return _findCommand;
}
}
private void Find()
{
// Here instead of writing large code,
// moving find logic to separate static class
SomeHelper.FindPerson(MainModel.SearchName);
}
因此,在这种情况下,Command是ViewModel
中调用方法的包装器。