我正在尝试找出删除模型的最佳方法(因此是VM),尽管进行了很多搜索,但我仍未找到满意的答案。
给定简化模型,给定一个包含自身列表的模型,以及随后的包含自身集合的viewmodel,应该以什么顺序通知和删除事物?
我的工作假设是流程类似
这似乎过于复杂,此方法将需要单独的逻辑来删除根项目,但是,如果具有视图调用它自己的deleteself命令,则意味着列表和集合中的空项目必须与父VM和模型进行通信。有删除模型的“典型”方法吗?
如果我现在必须写点东西,它将如下所示
模型
public class NestingBoxModel
{
public NestingBoxModel()
{
NestingBoxModels = new List<NestingBoxModel>();
}
public List<NestingBoxModel> NestingBoxModels { get; }
public Boolean ShouldBeRemoved { get; private set; }
/// <summary>
/// Notfies child to prepare for removal
/// </summary>
/// <param name="child">Child to be notified</param>
public void DeleteChild(NestingBoxModel child)
{
NestingBoxModels.Find(c => c == child)?.PrepareForRemoval();
}
/// <summary>
/// Notifes all children to prepare for removal
/// Marked as ready for removal
/// </summary>
public void PrepareForRemoval()
{
NestingBoxModels.ForEach(nb => nb.PrepareForRemoval());
ShouldBeRemoved = true;
}
// Other stuff for saving and eventually removing the model
}
ViewModel
public class NestingBoxViewModel : BindableBase
{
public NestingBoxViewModel()
{
Model = new NestingBoxModel();
ViewModels = new ObservableCollection<NestingBoxViewModel>();
DeleteChildCommand = new DelegateCommand<object>(DeleteChild);
DeleteCommand = new DelegateCommand(PrepareForRemoval);
}
public NestingBoxModel Model { get; private set; }
public ObservableCollection<NestingBoxViewModel> ViewModels { get; private set; }
public ICommand DeleteChildCommand { get; }
public ICommand DeleteCommand { get; }
/// <summary>
/// Finds, notifies, and removes child viewmodel
/// </summary>
/// <param name="child">Child viewmodel to be removed</param>
private void DeleteChild(object child)
{
var matchingchild = ViewModels.First<NestingBoxViewModel>(vm => vm.Equals(child));
if (matchingchild != null)
{
Model.DeleteChild(matchingchild.Model);
ViewModels.Remove(matchingchild);
matchingchild.PrepareForRemoval();
}
}
/// <summary>
/// Prepares for garbage collection
/// </summary>
public void PrepareForRemoval()
{
ViewModels.ToList<NestingBoxViewModel>().ForEach(vm => vm.PrepareForRemoval());
Model = null;
ViewModels = null;
}
}
查看
<Border Width="5">
<StackPanel Margin="10">
<Button Content="New NestingBox" Command="{Binding DeleteChildCommand, RelativeSource={RelativeSource TemplatedParent}}" CommandParameter="{Binding}"/>
<ItemsControl ItemsSource="{Binding ViewModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:NestingBoxView/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
如果它不是很乱,那肯定会造成混乱。
答案 0 :(得分:1)
- 用户点击子视图上的删除
- 该视图从父视图的数据上下文中调用DeleteChild命令,并将其自身的数据上下文作为参数传递
- 父VM通知其Model(父模型)正在删除其子VM之一
- 父VM从其集合中删除子VM
- 父模型删除子模型
就是这样。我要添加
3a。该模型广播有关其子级之一被删除的通知
因为视图模型不应更改自己镜像模型集合的视图模型集合。推理:模型集合很可能在没有视图模型做任何事情的情况下发生更改,因此无论如何它都必须对更改做出反应,并且您可以免费获得对源自视图模型的更改的响应。