c# - 如何在其父级的ViewModel和Model的集合中删除ViewModel和Model

标签 c# wpf mvvm prism

我正在尝试找出删除模型的最佳方法(因此是VM),尽管进行了很多搜索,但我仍未找到满意的答案。

简化版本是给定一个包含自身列表的模型,以及随后的包含自身集合的viewmodel,应按什么顺序通知和删除事物?

我的工作假设是流程像

  • 用户单击 subview 上的删除
  • 该 View 从父 View 的数据上下文中调用DeleteChild命令,并将其自身的数据上下文作为参数
  • 传递
  • 父VM通知其模型(父模型)它正在删除其子VM之一
  • 父VM从子VM的集合中删除子VM
  • 父模型删除子模型

  • 似乎几乎太复杂了,此方法将需要单独的逻辑来删除根项目,但是,如果调用 View 本身的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
    }
    

    View 模型
    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>
    

    如果不是很乱,那肯定会造成困惑。

    最佳答案

    1. User clicks delete on a child view
    2. The view calls the DeleteChild command from the parent view's datacontext, passing it's own datacontext as a parameter
    3. The parent VM notifies it's Model (the parent model) that it's deleting one of it's children's VMs
    4. The parent VM removes the child VM from it's collection
    5. The parent model removes the child model


    就是这样。我会加

    3a. the Model broadcasts a notification about one of its children being removed



    因为 View 模型不应更改自己镜像模型集合的 View 模型集合。推理:模型集合很可能在没有 View 模型做任何事情的情况下发生更改,因此无论如何它都必须对更改使用react,并且您可以免费获得对源自 View 模型的更改的响应。

    关于c# - 如何在其父级的ViewModel和Model的集合中删除ViewModel和Model,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52436475/

    相关文章:

    c# - 无法通过 ASP.NET 应用程序发送电子邮件

    c# - 在新线程中运行函数 C# Windows 应用程序

    c# - 如何将 groupBox 的角更改为尖角而不是圆形 C# .NET WPF

    c# - 将 SecureString 放入 PasswordBox

    wpf - 命令绑定(bind)到 ContextMenu(在 ListBox 中的 ListBoxItem 上)不起作用

    c# - .net开发代码结构-Controllers, Services, Repositories & Contexts

    c# - 在 C# 中的标签中显示 mySql 表

    c# - 当您必须直接引用控件时,MVVM 如何适应 WPF

    asp.net-mvc - MVVM View 模型与 MVC View 模型

    c# - 如何防止 ViewModel 构造函数被调用两次?