下面的第一个代码部分是我很想写的代码。下面的第二个代码部分是以前的代码工作者在尝试完成相同任务时编写的。
之前同事的代码似乎遵循标准的 MVVM 实践,即为每种类型的项目设置单独的 ViewModel,跟踪 ViewModel 中的 SelectedItems 而不是视图,以及避免模型中的 ObservableCollection。
我很想写的代码的大小和复杂度只有一半左右,模型和 ViewModel 不同步的可能性更小,代码行数也少得多。
MVVM 最佳实践真的是正确的答案吗?是否有某种中间立场结合了两个版本的优点?
我的代码:
//Model
public class Cheese
{
public string Name { get; set; }
public int Tastiness { get; set; }
public Color Color { get; set; }
}
public class CheeseEditorModel
{
public ObservableCollection<Cheese> Cheeses { get; private set; }
public CheeseEditorModel()
{
//read cheeses in from file/database/whatever
}
public DeleteCheeses(SelectedObjectCollection selected)
{
//delete cheeses
}
}
//ViewModel
public class CheeseEditorViewModel
{
private CheeseEditorModel _model;
public ObservableCollection<Cheese> Cheeses { get {return _model.Cheeses} }
public CheeseEditorViewModel()
{
_model = new CheeseEditorModel();
}
public DeleteSelected(SelectedObjectCollection selected)
{
_model.Delete(selected);
}
}
//XAML
<ListBox Name="CheeseListBox" ItemsSource={Binding Path="Cheeses"} />
<Button Command={Binding DeleteSelected} CommandParameter="{Binding ElementName=CheeseListBox, Path=SelectedItems}" />
别人的代码:
//Model
public class Cheese
{
public string Name { get; set; }
public int Tastiness { get; set; }
public Color Color { get; set; }
}
public class CheeseEditorModel
{
public List<Cheese> Cheeses { get; private set; }
public CheeseDataModel()
{
//read cheeses in from file/database/whatever
}
public DeleteCheeses(IEnumerable<Cheese> toDelete)
{
//delete cheeses
}
}
//ViewModel
public class CheeseViewModel
{
private Cheese _cheese { get; set; }
public bool IsSelected { get; set; }
public CheeseViewModel(Cheese cheese)
{
_cheese = cheese;
IsSelected = false;
}
public string Name {get {return _cheese.Name} set { _cheese.Name = value } }
public int Tastiness {get {return _cheese.Tastiness} set { _cheese.Tastiness= value } }
public Color Color {get {return _cheese.Color} set { _cheese.Color = value } }
}
public class CheeseEditorViewModel
{
private CheeseEditorModel _model;
public ObservableCollection<CheeseViewModel> Cheeses { get; private set; }
public CheeseEditorViewModel()
{
_model = new CheeseEditorModel();
foreach (cheese in _model.Cheeses)
Cheeses.Add(cheese);
}
public DeleteSelected()
{
var selected = from cheese in Cheeses select cheese.CheeseModel where cheese.IsSelected();
_model.Delete(selected);
var selectedVM = from cheese in Cheeses select cheese where cheese.IsSelected();
foreach (cheese in selectedVM)
Cheeses.Remove(selected);
}
}
//XAML
<ListBox ItemsSource={Binding Path="Cheeses"}>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button Command={Binding DeleteSelected} />