gpt4 book ai didi

c# - MVVM实现中的疑惑

转载 作者:太空宇宙 更新时间:2023-11-03 15:21:39 24 4
gpt4 key购买 nike

这是我实现的架构。

enter image description here

基本上我想在 View 2 中选择“单元格”,然后“位置”将从所选单元格中填充。然后我有带有“系统”的组合框,我希望在系统选择时填充不同的单元格集。为此,我使用 IOC 来访问不同的 View 模型。

疑惑是我有没有按照MVVM模式实现。 UpdateModel 部分对我来说看起来不太好。如果有人可以审查体系结构并告诉我我可以做得更好,我将不胜感激。在 View 模型中拥有模型实例是否正确,或者我应该使用数据服务模式,比如在 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");
}

View 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);
}
}

最佳答案

此处的部分答案可解决您对架构的一些代码异味和疑虑:

  1. ViewModel 不应了解其他 ViewModel,因此 ViewModel1 不应调用 ViewModel2。

  2. 如果可能,不应使用 ServiceLocator。 ViewModelLocator 只能由框架使用,不能直接调用。如果您解决了问题 1,那么此问题也会消除。

  3. 模型可以实现 INotifyPropertyChanged 以及 ViewModel。通过这种方式,您可以将 SelectedSystem、SelectedCell 和 SelectedLocation 的属性放在模型上,并让它们触发 PropertyChanged 事件。

  4. 使用您的 ViewModel 从某种类型的存储库中提取您的模型。这样,当 ViewModels 更新它们的属性时,模型的状态将被持久化。 ViewModels 可能会或可能不会根据 ViewModelLocator 的内部工作方式保持状态。使用模型和/或存储库来确保状态持续到 ViewModel 的生命周期之外。

  5. 对 ViewModel 和 Model 中的几乎所有集合类型使用 ObservableCollections,这样 View 就可以绑定(bind)到这些类型,而不必在 getter 上执行太多逻辑。根据经验,如果您想在 View 上查看任何值或集合,请确保它们是可观察的。这将允许使用 MVVM 绑定(bind)的全部功能,并删除大量试图保持 View 更新的样板代码。

关于c# - MVVM实现中的疑惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37103808/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com