在WPF应用程序中使用MVVM模式删除TreeViewitem

Bnolor.

新成员
加入
3月31日,2021年
消息
4
编程经验
Beginner
我正在使用C#WPF中使用MVVM模式进行文件资源管理器应用程序。现在我想实现负责添加,删除和从TreeView中重命名项目的观察者事件。我已经添加了,部分重命名(我认为在这种情况下,我必须组合删除和添加)。我正在挣扎删除。

已删除的文件仍在TreeView中。这是一个应用程序窗口。例如,文件夹2不应该存在,因为我删除了它。
1617210840037.png.


我面临着截止行动的截止日期,我非常欣赏任何帮助。这是我用class directoryinfoviewmodel写的代码

directoryinfoviewmodel.cs:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;



namespace ViewModels

{

    public class DirectoryInfoViewModel : FileSystemInfoViewModel

    {

        public ObservableCollection<FileSystemInfoViewModel> Items { get; private set; }
= new ObservableCollection<FileSystemInfoViewModel>();



        public bool Open(string path)
        {
            bool result = false;

            try
            {
                 FileSystemWatcher Watcher = new FileSystemWatcher(path);
                Watcher.Created += OnFileCreated;
                Watcher.Renamed += OnFileRenamed;
                Watcher.Deleted += OnFileDeleted;
                //Watcher.Changed += OnFileChanged;
                Watcher.Error += Watcher_Error;
                Watcher.EnableRaisingEvents = true;

                foreach (var dirName in Directory.GetDirectories(path))
                {
                    var dirInfo = new DirectoryInfo(dirName);
                    DirectoryInfoViewModel itemViewModel = new DirectoryInfoViewModel
                    {
                        Model = dirInfo
                    };
                    itemViewModel.Open(dirName);
                    Items.Add(itemViewModel);
                }

                foreach (var fileName in Directory.GetFiles(path))
                {
                    var fileInfo = new FileInfo(fileName);
                    FileInfoViewModel itemViewModel = new FileInfoViewModel();
                    itemViewModel.Model = fileInfo;
                    Items.Add(itemViewModel);
                }

                result = true;

            }

            catch (Exception ex)
            {
                Exception = ex;
            }

            return result;
        }


        public Exception Exception { get; private set; }

        private static void Watcher_Error(object sender, ErrorEventArgs e) =>
            System.Windows.MessageBox.Show(e.GetException().ToString());

        public void OnFileCreated(object sender, FileSystemEventArgs e)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(() => OnFileCreated(e));
        }

        private void OnFileCreated(FileSystemEventArgs e)
        {
            Debug.WriteLine("File Created: " + e.Name);
            if (!Items.Any(x => x.Caption == e.Name))

            {

                var dirInfo = new DirectoryInfo(e.FullPath);
                DirectoryInfoViewModel itemViewModel = new DirectoryInfoViewModel();
                itemViewModel.Model = dirInfo;
                Items.Add(itemViewModel);

            }

        }


        public void OnFileDeleted(object sender, FileSystemEventArgs e)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(() => OnFileDeleted(e));
        }

        private void OnFileDeleted(FileSystemEventArgs e)
        {


                Debug.WriteLine("File Deleted: " + e.Name);
            if (Items.Any(x => x.Caption == e.Name))
            {
                var dirInfo = new DirectoryInfo(e.FullPath);
                Debug.WriteLine("File path: " + e.FullPath);
                DirectoryInfoViewModel itemViewModel = new DirectoryInfoViewModel();

                itemViewModel.Model = dirInfo;
                Items.Remove(itemViewModel);         
            }

        }

        public void OnFileRenamed(object sender, FileSystemEventArgs e)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(() => OnFileRenamed(e));
        }

        private void OnFileRenamed(FileSystemEventArgs e)

        {
            Debug.WriteLine("File Renamed: " + e.Name);
            OnFileDeleted(e);
            OnFileCreated(e); 
        }

    }

}
 
Last edited:
Solution
这不是WPF或MVVM问题。这是一个基本的面向对象编程问题。

让想象这段情景有一个果实列表的场景:
C#:
class Fruit
{
    public string Name { get; set; }
}

:

var apple = new Fruit() { Name = "Apple" };
var orange = new Fruit() { Name = "Orange" };
var pear = new Fruit() { Name = "Pear" };

var list = new List<Fruit>();
list.Add(apple);
list.Add(orange);
list.Add(pear);

这就是您目前正在做的:
C#:
if (list.Any(f => f.Name == "Apple"))
{
    var apple2 = new Fruit() { Name = "Apple" };
    list.Remove(apple2);
}

The Remove() won't find a matching item to remove. That's because apple2 is a different instance than the original...

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,890
地点
切萨皮克,va.
编程经验
10+
您正在115行创建一个新实例。这与可观察到的集合中已有的实例不匹配。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,890
地点
切萨皮克,va.
编程经验
10+
这不是WPF或MVVM问题。这是一个基本的面向对象编程问题。

让想象这段情景有一个果实列表的场景:
C#:
class Fruit
{
    public string Name { get; set; }
}

:

var apple = new Fruit() { Name = "Apple" };
var orange = new Fruit() { Name = "Orange" };
var pear = new Fruit() { Name = "Pear" };

var list = new List<Fruit>();
list.Add(apple);
list.Add(orange);
list.Add(pear);

这就是您目前正在做的:
C#:
if (list.Any(f => f.Name == "Apple"))
{
    var apple2 = new Fruit() { Name = "Apple" };
    list.Remove(apple2);
}

The Remove() won't find a matching item to remove. That's because apple2 is a different instance than the original apple that was put into the list.

你想要发生的事情应该是:
C#:
if (list.Any(f => f.Name == "Apple"))
{
    list.Remove(apple);
}

因为它只是为了给你如何在列表中找到原来的Apple的答案,我会让你自己工作,因为它将帮助你加强不同实例的概念,这可能具有相同的领域价值观。
 
解决方案

Bnolor.

新成员
加入
3月31日,2021年
消息
4
编程经验
Beginner
这不是WPF或MVVM问题。这是一个基本的面向对象编程问题。

让想象这段情景有一个果实列表的场景:
C#:
class Fruit
{
    public string Name { get; set; }
}

:

var apple = new Fruit() { Name = "Apple" };
var orange = new Fruit() { Name = "Orange" };
var pear = new Fruit() { Name = "Pear" };

var list = new List<Fruit>();
list.Add(apple);
list.Add(orange);
list.Add(pear);

这就是您目前正在做的:
C#:
if (list.Any(f => f.Name == "Apple"))
{
    var apple2 = new Fruit() { Name = "Apple" };
    list.Remove(apple2);
}

The Remove() won't find a matching item to remove. That's because apple2 is a different instance than the original apple that was put into the list.

你想要发生的事情应该是:
C#:
if (list.Any(f => f.Name == "Apple"))
{
    list.Remove(apple);
}

因为它只是为了给你如何在列表中找到原来的Apple的答案,我会让你自己工作,因为它将帮助你加强不同实例的概念,这可能具有相同的领域价值观。
我想出了这样的东西:
OnFileDeleted:
private void OnFileDeleted(FileSystemEventArgs e)

{

    if (Items.Any(x => x.Caption == e.Name))

    {

        var toDelete = Items.Single(x => x.Caption == e.Name);

        Items.Remove(toDelete);

    }

}
删除作品,但不完全。例如,当我删除时,一切都能完美地工作。但是,当我尝试删除包含其他子文件夹的文件夹时,我会出现错误说明"Access denied"。你有关于如何解决它的想法吗?
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,890
地点
切萨皮克,va.
编程经验
10+
Callstack是什么样的?哪里是"Access denied"来自(哪里?通常对于Windows,如果您尝试删除非空文件夹,则会收到错误。
 

Bnolor.

新成员
加入
3月31日,2021年
消息
4
编程经验
Beginner
我担心在onfileDeleted开头设置断点后,我的Callstack是空的,因为我尝试删除包含其他子文件夹的文件夹和删除,无法进行)。
删除包含.txt的文件夹时没有问题。 (没有其他文件夹)。到iLustrate,当我删除文件夹3时,一切都可以。
1617309182846.png

但是,如果我尝试删除文件夹('root')或文件夹2,我会得到以下错误(对不起,它是在波兰语中,但被说我没有管理员权限):
1617309331526.png.

当我按下继续时,我最终结束(从用户获得权限):

1617309377805.png.


辅助,我收到Watcher_Error的错误(访问拒绝):
1617309493859.png.

我希望现在我更准确地说我的问题。
 
Last edited:

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,890
地点
切萨皮克,va.
编程经验
10+
我不确定,但是,to watch_error()的调用看起来是一个迟到的通知,即运行的未拉的用户正在尝试删除它们没有权限的东西。我不认为你可以做些什么。

此异常与WPF或MVVM无关。它是一个操作系统级别问题和/或.NET问题。您可以尝试查看.NET Framework的执行该文件的源代码和目录观察者的实施者,以便更有洞察会探讨抛出异常的原因。
 
最佳 底部