这是我实施的架构。
基本上我想在视图2中选择“单元格”,并且将从所选单元格中填充“位置”。然后我有“系统”的组合框,我想要系统选择,以填充不同的单元格集。为此,我使用IOC访问不同的视图模型。
怀疑是我是否已根据MVVM模式实现。 UpdateModel
的部分对我来说不太好看。如果有人可以审查架构并告诉我我可以做得更好,我将不胜感激。在视图模型中使用模型实例也是正确的,或者我应该使用数据服务模式,就像在mvvm-light样板中一样?
问题:我是否可以在不调用UpdateModel函数的情况下实现对系统更改的响应,但使用mvvm-light的本机机制来更新ViewModel2?
代码的一些关键部分。
ViewModel2:
public List<string> LocationList
{
get
{
var cells = _wList.GetCells(currentSystemNumber);
var cell = cells[_selectedCellItem.Key];
return cell.Locations;
}
}
private KeyValuePair<int, string> _selectedCellItem;
public KeyValuePair<int, string> SelectedCellItem
{
get
{
return _selectedCellItem;
}
set
{
Set(ref _selectedCellItem, value);
RaisePropertyChanged("LocationList");
}
}
public ObservableCollection<KeyValuePair<int, string>> CellList
{
get
{
int count = _wList.GetCells(currentSystemNumber).Count;
ObservableCollection<KeyValuePair<int, string>> cells = new ObservableCollection<KeyValuePair<int, string>>();
for(int i = 0; i < count; i++)
cells.Add(new KeyValuePair<int, string>(i, string.Format("Cell {0}/{1}", i, currentSystemNumber+1)));
return cells;
}
}
public void UpdateModel(int system)
{
currentSystemNumber = system;
RaisePropertyChanged("CellList");
RaisePropertyChanged("LocationList");
}
视图2:
<Grid>
<ListBox x:Name="listBox" HorizontalAlignment="Left" Height="104" Margin="121,32,0,0" VerticalAlignment="Top" Width="144" ItemsSource="{Binding LocationList}"/>
<ListBox x:Name="listBox1" HorizontalAlignment="Left" Height="104" Margin="10,32,0,0" VerticalAlignment="Top" Width="102" ItemsSource="{Binding CellList}" SelectedItem="{Binding SelectedCellItem}" DisplayMemberPath="Value"/>
<Label x:Name="label" Content="Cells" HorizontalAlignment="Left" Margin="10,1,0,0" VerticalAlignment="Top"/>
<Label x:Name="label1" Content="Locations" HorizontalAlignment="Left" Margin="121,1,0,0" VerticalAlignment="Top"/>
</Grid>
ViewModel1:
private ObservableCollection<KeyValuePair<int, string>> _systems = new ObservableCollection<KeyValuePair<int, string>>();
public ObservableCollection<KeyValuePair<int, string>> Systems
{
get
{
return _systems;
}
}
private KeyValuePair<int, string> _selectedSystemItem;
public KeyValuePair<int, string> SelectedSystemItem
{
get
{
return _selectedSystemItem;
}
set
{
Set(ref _selectedSystemItem, value);
var locator = (ViewModelLocator)Application.Current.Resources["Locator"];
var vm = locator.DASrvPageVM;
vm.UpdateModel(value.Key);
}
}
答案 0 :(得分:0)
这里的部分答案是为了解决您的架构中的一些代码气味和疑问:
ViewModels不应该了解其他ViewModel,因此ViewModel1不应该调用ViewModel2。
如果可能的话,不应该使用ServiceLocator。 ViewModelLocator只应由框架使用,不能直接调用。如果您修复问题1,那么也会删除此问题。
模型可以实现INotifyPropertyChanged以及ViewModel。这样,您可以在模型上放置SelectedSystem,SelectedCell和SelectedLocation的属性,并激活PropertyChanged事件。
使用ViewModel从某种类型的存储库中提取模型。这样,当ViewModel更新其属性时,模型的状态将保持不变。 ViewModel可能会也可能不会根据ViewModelLocator在内部的工作方式保持状态。使用模型和/或存储库可确保状态持续超出ViewModel的生命周期。
对ViewModel和Models中的几乎所有集合类型使用ObservableCollections,以便Views可以绑定到这些集合类型,而无需在getter上执行如此多的逻辑。经验法则,如果您想在View上查看任何值或集合,请确保它们是Observable。这将允许使用MVVM绑定的全部功能,并删除大量试图保持View更新的样板代码。