Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.88/17: Рейтинг темы: голосов - 17, средняя оценка - 4.88
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
.NET 4.x

Отображение и управления папками и файлами внутри списка папок

22.10.2023, 20:19. Показов 4449. Ответов 47
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Нужен элемент или набор элементов чтобы организовать вывод и управление папками и файлами внутри списка папок проекта.
Список папок проекта это список объектов класса хранящих имя проекта и полный путь до папки проекта.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Serializable]
public class SFNPath
{
    public string Name { get; set; }
    public string Path { get; set; }
 
    [JsonConstructor]
    public SFNPath()
    {
        Name = "";
        Path = "";
    }
 
    public SFNPath(string name, string path)
    {
        Name = name;
        Path = path;
    }
}
...
public List<SFNPath> AllDirProjects
По поводу управление то это мини проводник без всех параметров проводника но с его контекстным меню. А следовательно нужна возможность нескольких выделений папок и файлов.
К слову за пределы папки с проектом нельзя должно быть выходить только в пределах списка папок с проектами тобишь они и то что в них.
Подскажите пожалуйста какой элемент для этого взять. Хорошо бы отображение делать в виде дерева но TreeView во первых не даёт делать выделение нескольких элементов а во вторых не очень предназначен для хранения большого количества элементов в том плане что обновление например при переименовании и удалении будет происходить очень долго.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.10.2023, 20:19
Ответы с готовыми решениями:

Процедура удаления папок со вложенными файлами и папками
помогите написать процедуру удаления папок со вложенными файлами и папками

Нужен скрипт перемещения нужных папок с файлами внутри
Здравствуйте, есть папки Telegram (1), Telegram (2)... идущие по порядку. В каждой из них находится папка tdata с разными папками и...

Отображение списка файлов и папок в каталоге.
Некорректно работает программа. Вот кусок кода, отвечающий за вывод списка файлов и папок в папке. HANDLE Search; WIN32_FIND_DATAA...

47
478 / 241 / 74
Регистрация: 25.05.2012
Сообщений: 1,139
Записей в блоге: 1
27.10.2023, 14:23
Студворк — интернет-сервис помощи студентам
Alexandr_7, главное чтоб в итоге работало как задумывалось

Добавлено через 11 минут
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Delete надо переделывать. При любом из этих действий нужно делать перепоиск.
Зачем?
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Но в случае переименовании у имён проектов (а это по сути корневая папка) имя корневой папки не обязательно будет именем папки.
Можно добавить новое свойство, например, .DisplayedName.
Если папка не корневая, то принудительно возвращать .Name, если корневая - то разрешить задавать произвольное значение.

Добавлено через 1 минуту
Ну и в конструкторе его тоже инициализировать, разумеется
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
27.10.2023, 14:57  [ТС]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
[Serializable]
public class SFNPath
{
    public string Text { get; set; }
    public string FullName { get; set; }
 
    [JsonIgnore]
    public bool IsDir { get => Directory.Exists(FullName); }
    [JsonIgnore]
    public bool IsFile { get => File.Exists(FullName); }
 
    [JsonIgnore]
    public string Name { get => Path.GetFileName(FullName); }
    [JsonIgnore]
    public string NameWithoutExtension { get => IsFile ? Path.GetFileNameWithoutExtension(FullName) : Name; }
 
    [JsonConstructor]
    public SFNPath()
    {
        Text = "";
        FullName = "";
    }
 
    public SFNPath(string text, string fullName)
    {
        Text = text;
        FullName = fullName;
    }
}
 
public class SFNPathInfo: SFNPath
{
    private List<SFNPathInfo> _pathList;
 
    private SFNPathInfo _parent;
 
    public SFNPathInfo(string text, string fullName)
    {
        Text = text;
        FullName = fullName;
        _pathList = null;
        _parent = null;
 
    }
 
    public SFNPathInfo(SFNPathInfo parent, string text, string fullName)
    {
        Text = text;
        FullName = fullName;
        _pathList = null;
        _parent = parent;
    }
 
    public SFNPathInfo Parent { get => _parent; }
 
    public bool IsRoot => Parent == null;
 
    public List<SFNPathInfo> PathList
    {
        get
        {
            if (_pathList != null)
            {
                return _pathList;
            }
 
            if (IsFile)
            {
                return new List<SFNPathInfo>();
            }
            else if (IsDir)
            {
                _pathList = Directory.GetFileSystemEntries(FullName)
                .Select(filePath => new SFNPathInfo(this, Path.GetFileName(filePath), filePath))
                .ToList();
            }
 
            return _pathList;
        }
    }
 
    public int CountDirs
    {
        get => _pathList == null ? 0 : _pathList.Select(x => x.IsDir).Count();
    }
 
    public int CountFiles
    {
        get => _pathList == null ? 0 : _pathList.Select(x => x.IsFile).Count();
    }
 
    public int CountData
    {
        get => _pathList == null ? 0 : _pathList.Count();
    }
}
Переделал. Так наверное структура получше будет.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
29.10.2023, 05:56  [ТС]
Кстати а можно такой дизайн сделать у TreeListView:

В TreeView такой дизайн я делаю:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static class DllImports
{
    [DllImport("uxtheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)]
    public static extern int SetWindowTheme(IntPtr hwnd, string pszSubAppName, string pszSubIdList);
}
...
public partial class WinTreeView: TreeView
{
    public PathTreeNode SelectedPathNode { get => (PathTreeNode)SelectedNode; }
 
    protected override void CreateHandle()
    {
        base.CreateHandle();
        DllImports.SetWindowTheme(this.Handle, "explorer", null);
    }
 
    protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
    {
        this.SelectedNode = e.Node;
        base.OnNodeMouseClick(e);
    }
}
Иконки такие точно есть в TreeListView но речь не только про иконки но и про выделение элементов.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
31.10.2023, 16:22  [ТС]
Не могу вообще разобраться с настройкой дизайна columns например сделать 2 поля размер которых первого был по размеру текста а второй всю область.

Добавлено через 32 минуты
Ещё мне также необходимо чтобы выделялись все Columns а не только первый в котором я планирую отображать тип данных
0
478 / 241 / 74
Регистрация: 25.05.2012
Сообщений: 1,139
Записей в блоге: 1
31.10.2023, 16:39
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Не могу вообще разобраться с настройкой дизайна columns например сделать 2 поля размер которых первого был по размеру текста а второй всю область.
Свойство колонки .FillsFreeSpace?

Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Ещё мне также необходимо чтобы выделялись все Columns а не только первый в котором я планирую отображать тип данных
Свойство компонента .FullRowSelect?
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
31.10.2023, 19:24  [ТС]
Окей. Следующее что нужно сделать это вместо плюсиков рисовать стрелочки ну короче как в проводнике винды.

Добавлено через 28 минут
Ещё не могу разобраться с отображением иконки.
0
478 / 241 / 74
Регистрация: 25.05.2012
Сообщений: 1,139
Записей в блоге: 1
01.11.2023, 09:58
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Окей. Следующее что нужно сделать это вместо плюсиков рисовать стрелочки ну короче как в проводнике винды.
https://objectlistview.sourcef... like-vista
?
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Ещё не могу разобраться с отображением иконки.
Есть и в примере и в документации
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
01.11.2023, 11:21  [ТС]
Цитата Сообщение от NewOrdered Посмотреть сообщение
Есть и в примере и в документации
По примеру что здесь скидывали вообще не понятно как происходит лично я получаю ошибку Экземпляр объекта не указывает на объект.
Цитата Сообщение от NewOrdered Посмотреть сообщение
https://objectlistview.sourcef... like-vista
?
Ну если включить UseExplorerTheme то дерево проподает. А UseTransluscentSelection и UseTranslucentHotItem влияют только на выделение а не иконки стрелочек вместо плюсиков.
0
478 / 241 / 74
Регистрация: 25.05.2012
Сообщений: 1,139
Записей в блоге: 1
01.11.2023, 13:32
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
По примеру что здесь скидывали вообще не понятно как происходит лично я получаю ошибку Экземпляр объекта не указывает на объект.
А если внимательнее документацию читать, то окажется

The value returned from the ImageGetter delegate is used as an index into the ObjectListView‘s SmallImageList.
..
You need to make an ImageList, give it the images you want, and then assign it to the SmallImageList property of the ObjectListView.
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
вместо плюсиков рисовать стрелочки
таких примеров не встречалось
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
20.01.2024, 20:54  [ТС]
Цитата Сообщение от NewOrdered Посмотреть сообщение
А если внимательнее документацию читать, то окажется
Да указывал я список в SmallImageList
Короче не особо могу разобраться с этим куском:
C#
1
2
3
4
_tptvFilesystem = new TypedObjectListView<FileSystemItem>(tvFilesystem);
_tpcolName = _tptvFilesystem.GetColumn("Name");
...
_tpcolName.ImageGetter = GetIconKey;
В GetColumn какое имя нужно передавать. Дело в том что у меня только 2 Колумна. Колум с типом данных (Папка или файл) и колум с текстом. Но текст не равно полному имени. Мне и не нужно чтоб треелист отображал полное имя.
Если писать в колумн имя свойства с полным именем на файл то всё равно ошибка Экземпляр объекта не указывает на объект.

Добавлено через 1 час 27 минут
Разобрался. Просто в GetColumn вместо имени поставил индекс колумна.
Но я не понимаю почему когда я ставлю UseExplorerTheme то дерево не отображается а только корневые папки. Какойто бред.

Добавлено через 1 час 13 минут
Мне нужно использовать стиль провордника винды для TreeListView и ещё открывать и закрывать итемы двойным кликом.
UseExplorerTheme судя по всему неработает у TreeListView а только у ObjectListView
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
10.08.2024, 20:22  [ТС]
Подскажите как после обновления (обнуления Roots и заново присвоения значения) в BrightIdeasSoftware.TreeListView восстановить выделенный элемент. Точнее я могу запомнить:
C#
1
var sellFile = treeListViewProjectData.SelectedObject;
Но как его потом найти.
У свойства Objects нету find да и к томуже это дерево. Надо искать такойже объект во всех. Просто если назад treeListViewProjectData.SelectedObject присвоить объект которого может и не быть наверняка вызовет ошибку.

Добавлено через 4 минуты
Нет. Это так просто в любом случае наработает.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
13.08.2024, 14:17  [ТС]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private void RefreshNodeProjects()
{
    IsRefreshProjects = true;
 
    treeListViewProjectData.Roots = null;
 
    if (CountEngineProjects > 0)
    {
        treeListViewProjectData.CanExpandGetter = obj => ((SFNPathInfo)obj).IsDir;
        treeListViewProjectData.ChildrenGetter = obj =>
        {
            try
            {
                return ((SFNPathInfo)obj).PathList;
            }
            catch (UnauthorizedAccessException ex)
            {
                // on error (e.g. restricted system dirs) show message box and collapse the subtree allowing the user to retry later
                // we cannot do this immediately in this getter because TreeListView will not react correctly and may remain in undefined state
                // so we use BeginInvoke to execute it a bit later on the UI thread
                BeginInvoke(new Action(() =>
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    treeListViewProjectData.Collapse(obj);
                }));
                return new List<SFNPathInfo>();
            }
        };
 
        treeListViewProjectData.ParentGetter = obj => ((SFNPathInfo)obj).Parent;
 
        treeListViewProjectData.Roots = SelectEngine.AllDirProjects;
 
        _tpcolName.ImageGetter = GetIconKey;
    }
    else
    {
        treeListViewProjectData.Roots = null;
    }
 
    pnlInfo.ScrollToRight();
 
    IsRefreshProjects = false;
}
Прошу помощи. Может кто сказать как потом вернуть выделенные данные или если они отсутствуют то выделить Parent.
Не могу найти способа это сделать.
0
478 / 241 / 74
Регистрация: 25.05.2012
Сообщений: 1,139
Записей в блоге: 1
14.08.2024, 13:00
Alexandr_7,

Ну вариант в лоб: перед строкой 5 получить ссылку на объект соответствующий выделенному элементу (treeListViewProjectData.SelectedObject / .SelectedObjects). Ну а после 32 строки задать свойства .SelectedObject (или .SelectedObjects для нескольких). Можно еще вызвать метод .EnsureModelVisible() чтобы раскрыть/прокрутить список до выделенного элемента

Добавлено через 1 минуту
Alexandr_7,
А зачем вообще отсоединять коллекцию?
C#
1
treeListViewProjectData.Roots = null;
Добавлено через 2 минуты
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Но как его потом найти.
не найти а просто присвоить обратно
C#
1
treeListViewProjectData.SelectedObject = sellFile;
Добавлено через 2 минуты
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Просто если назад treeListViewProjectData.SelectedObject присвоить объект которого может и не быть наверняка вызовет ошибку.
так перед присвоением надо убедиться что объект присутствует в исходной коллекции
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
14.08.2024, 14:39  [ТС]
Цитата Сообщение от NewOrdered Посмотреть сообщение
Alexandr_7,
А зачем вообще отсоединять коллекцию?
Потому что по другому обновить данные нельзя. В этой структуре SelectEngine.AllDirProjects является свойство. Оно получает все проекты из настроек. Проектами является тупо местонахождение их. Без обнуление treeListViewProjectData не обновляет данные при повторном вызове RefreshNodeProjects().
Цитата Сообщение от NewOrdered Посмотреть сообщение
treeListViewProjectData.SelectedObject = sellFile;
Да пробовал я это естественно убедившись что данные sellFile будут в одной из ветви.
Какбы они присваиваются в SelectedObject но никак не открывается ветвь. Вроде бы и присвоена а вроде бы с виду так как будто не выбрано.

Добавлено через 6 минут
Цитата Сообщение от NewOrdered Посмотреть сообщение
Можно еще вызвать метод .EnsureModelVisible() чтобы раскрыть/прокрутить список до выделенного элемента
Вызов этой функции я кстати не пробовал. Но дело ещё в другом. Хотелось бы при отсутствии данных sellFile (если они были удалены проводником) переход переходил к данным в котором они лежали проще говоря к свойству Parent. Вся структура списка классов:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
    public class SFNPathInfo: SFNPath
    {
        private List<SFNPathInfo> _pathList;
 
        private SFNPathInfo _parent;
 
        public SFNPathInfo(string text, string fullName)
        {
            Text = text;
            FullName = fullName;
            _pathList = null;
            _parent = null;
 
        }
 
        public SFNPathInfo(SFNPathInfo parent, string text, string fullName)
        {
            Text = text;
            FullName = fullName;
            _pathList = null;
            _parent = parent;
        }
 
        public SFNPathInfo Parent { get => _parent; }
 
        public SFNPathInfo RootParent
        { 
            get
            {
                var prt = Parent;
                var prt2 = prt;
                while (prt != null)
                {
                    prt = prt.Parent;
                    if (prt != null)
                        prt2 = prt;
                }
 
                if (prt2 == null) prt2 = this;
 
                return prt2;
            }
        }
 
        public bool IsRoot => Parent == null;
 
        public List<SFNPathInfo> PathList
        {
            get
            {
                if (_pathList != null)
                {
                    return _pathList;
                }
 
                if (IsFile)
                {
                    return new List<SFNPathInfo>();
                }
                else if (IsDir)
                {
                    _pathList = Directory.GetFileSystemEntries(FullName)
                    .Select(filePath => new SFNPathInfo(this, Path.GetFileName(filePath), filePath))
                    .ToList();
                }
 
                return _pathList;
            }
        }
 
        public RPGMakerType Type
        {
            get
            {
                var id = Array.IndexOf(RPGMakerParam.RPGMakerExt, Ext);
                return id >= 0 ? ((RPGMakerType)((byte)id)) : RPGMakerType.None;
            }
        }
 
        public SFNPathInfo GetProjectFile(RPGMakerType type)
        {
            var rootPath = RootParent;
            List<SFNPathInfo> fns = new List<SFNPathInfo>();
            for (var i = 1; i < RPGMakerParam.RPGMakerExt.Length; i++)
            {
                fns = RootParent.PathList;
                if (fns.Count > 0)
                    break;
            }
 
            SFNPathInfo retFN = null;
 
            foreach (var fn in fns)
            {
                if (fn.IsDir) continue;
 
                if (type == RPGMakerParam.GetRMTypeExt(fn.Ext))
                {
                    retFN = fn;
                }
            }
 
            return retFN;
        }
 
        public bool CreatePDLCPath()
        {
            if (IsDir && !IsPDLCPath)
            {
                Directory.CreateDirectory(Path.Combine(FullName, "PDLC"));
                return true;
            }
            else return false;
        }
 
        private string TypeTextExt
        {
            get => Type == RPGMakerType.None ? Ext : RPGMakerParam.RPGMakerNames[(byte)Type];
        }
 
        public string TypeText { get => IsDir ? Languages.TX_DIR : IsFile ? TypeTextExt : Languages.TX_UNKNOWN; }
 
 
        public bool IsPDLCPath
        {
            get => IsDir ? Directory.Exists(Path.Combine(FullName, "PDLC")) ? true : false : false;
        }
 
        public int CountDirs
        {
            get => _pathList == null ? 0 : _pathList.Select(x => x.IsDir).Count();
        }
 
        public int CountFiles
        {
            get => _pathList == null ? 0 : _pathList.Select(x => x.IsFile).Count();
        }
 
        public int CountData
        {
            get => _pathList == null ? 0 : _pathList.Count();
        }
    }
0
 Аватар для Andrey-MSK
3386 / 2272 / 388
Регистрация: 14.08.2018
Сообщений: 7,689
Записей в блоге: 4
14.08.2024, 15:10
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Потому что по другому обновить данные нельзя.
Какой тип для коллекции используется? Для автоматического обновления UI при изменении коллекции нужно использовать привязки и коллекции типа BindingList<T>. И тогда, при изменении количества элементов коллекции UI обновится сам...
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
14.08.2024, 16:24  [ТС]
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Какой тип для коллекции используется? Для автоматического обновления UI при изменении коллекции нужно использовать привязки и коллекции типа BindingList<T>. И тогда, при изменении количества элементов коллекции UI обновится сам...
Это по моему неработает. Но в данном случае обычный List. Но вопрос в выделении элемента остался например если ранее выделенный элемент был удален необходимо выделять элемент в котором он находился.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3460 / 2781 / 575
Регистрация: 04.09.2018
Сообщений: 8,743
Записей в блоге: 3
14.08.2024, 16:47
Alexandr_7, если сильно приближенно, то тебе нужны три класса:
Root - это корни всех "проектов/папок", т.е. выше их иерархия не строится;
Folder - папки, которые находятся внутри Root'ов а так же, могут быть вложены друг в друга;
File - класс файлов, могут быть как внутри Root'ов, так и внутри Folder'ов.

Во всех этих классах должно быть свойство типа bool IsSelected, которое отражает факт - выбран/не выбран был элемент в списке (коллекции).

Далее, в отображаемом дереве или что там у тебя - при выделении элемента(ов) соотв. их свойства IsSelected устанавливаются. Таким образом в коллекции привязки у тебя уже определены выделенные элементы, которые легко получить, например так: var selectedItems = collection.Where(i => i.IsSelected == true);
Обходим снова "дерево" и устанавливаем у его элементов свойство Selected, согласно полученной выше коллекции.
Таких элементов может быть как один, так и несколько.

Цитата Сообщение от Alexandr_7 Посмотреть сообщение
если ранее выделенный элемент был удален необходимо выделять элемент в котором он находился
Тут многое зависит от момента самого определения факта удаления, т.е. "синхронно" удалять объект из коллекции или помечать как "удаленный". Тогда определить что выделять (элемент по иерархии выше) проще простого - просто установить у него свойство IsSelected...

Добавлено через 2 минуты
Цитата Сообщение от wizard41 Посмотреть сообщение
то тебе нужны три класса
... или даже два, без класса Root, но в Folder добавить свойство IsRoot...
Короче, нафантазировать можно что угодно как это реализовать.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
14.08.2024, 16:57  [ТС]
Цитата Сообщение от NewOrdered Посмотреть сообщение
Ну вариант в лоб: перед строкой 5 получить ссылку на объект соответствующий выделенному элементу (treeListViewProjectData.SelectedObject /.SelectedObjects). Ну а после 32 строки задать свойства .SelectedObject (или .SelectedObjects для нескольких). Можно еще вызвать метод .EnsureModelVisible() чтобы раскрыть/прокрутить список до выделенного элемента
Нет. Не работает способ:
C#
1
2
3
4
var selObj = treeListViewProjectData.SelectedObject;
...
treeListViewProjectData.SelectedObject = selObj;
treeListViewProjectData.EnsureModelVisible(selObj);
Добавлено через 7 минут
Функция RefreshNodeProjects() вызывается при смене движка или при отсуствие файла
А вообще код пока такой:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
    [Serializable]
    public class SFNPath
    {
        public string Text { get; set; }
        public string FullName { get; set; }
 
        [JsonIgnore]
        public bool IsDir { get => Directory.Exists(FullName); }
        [JsonIgnore]
        public bool IsFile { get => File.Exists(FullName); }
 
        [JsonIgnore]
        public string Name { get => Path.GetFileName(FullName); }
        [JsonIgnore]
        public string NameWithoutExtension { get => IsFile ? Path.GetFileNameWithoutExtension(FullName) : Name; }
        [JsonIgnore]
        public string Ext { get => Path.GetExtension(FullName); }
        [JsonIgnore]
        public string DirectoryFullName { get => IsFile ? Path.GetDirectoryName(FullName) : FullName; }
 
        [JsonConstructor]
        public SFNPath()
        {
            Text = "";
            FullName = "";
        }
 
        public SFNPath(string text, string fullName)
        {
            Text = text;
            FullName = fullName;
        }
    }
 
    public class SFNPathInfo: SFNPath
    {
        private List<SFNPathInfo> _pathList;
 
        private SFNPathInfo _parent;
 
        public SFNPathInfo(string text, string fullName)
        {
            Text = text;
            FullName = fullName;
            _pathList = null;
            _parent = null;
 
        }
 
        public SFNPathInfo(SFNPathInfo parent, string text, string fullName)
        {
            Text = text;
            FullName = fullName;
            _pathList = null;
            _parent = parent;
        }
 
        public SFNPathInfo Parent { get => _parent; }
 
        public SFNPathInfo RootParent
        { 
            get
            {
                var prt = Parent;
                var prt2 = prt;
                while (prt != null)
                {
                    prt = prt.Parent;
                    if (prt != null)
                        prt2 = prt;
                }
 
                if (prt2 == null) prt2 = this;
 
                return prt2;
            }
        }
 
        public bool IsRoot => Parent == null;
 
        public List<SFNPathInfo> PathList
        {
            get
            {
                if (_pathList != null)
                {
                    return _pathList;
                }
 
                if (IsFile)
                {
                    return new List<SFNPathInfo>();
                }
                else if (IsDir)
                {
                    _pathList = Directory.GetFileSystemEntries(FullName)
                    .Select(filePath => new SFNPathInfo(this, Path.GetFileName(filePath), filePath))
                    .ToList();
                }
 
                return _pathList;
            }
        }
 
        public RPGMakerType Type
        {
            get
            {
                var id = Array.IndexOf(RPGMakerParam.RPGMakerExt, Ext);
                return id >= 0 ? ((RPGMakerType)((byte)id)) : RPGMakerType.None;
            }
        }
 
        public SFNPathInfo GetProjectFile(RPGMakerType type)
        {
            var rootPath = RootParent;
            List<SFNPathInfo> fns = new List<SFNPathInfo>();
            for (var i = 1; i < RPGMakerParam.RPGMakerExt.Length; i++)
            {
                fns = RootParent.PathList;
                if (fns.Count > 0)
                    break;
            }
 
            SFNPathInfo retFN = null;
 
            foreach (var fn in fns)
            {
                if (fn.IsDir) continue;
 
                if (type == RPGMakerParam.GetRMTypeExt(fn.Ext))
                {
                    retFN = fn;
                }
            }
 
            return retFN;
        }
 
        public bool CreatePDLCPath()
        {
            if (IsDir && !IsPDLCPath)
            {
                Directory.CreateDirectory(Path.Combine(FullName, "PDLC"));
                return true;
            }
            else return false;
        }
 
        private string TypeTextExt
        {
            get => Type == RPGMakerType.None ? Ext : RPGMakerParam.RPGMakerNames[(byte)Type];
        }
 
        public string TypeText { get => IsDir ? Languages.TX_DIR : IsFile ? TypeTextExt : Languages.TX_UNKNOWN; }
 
 
        public bool IsPDLCPath
        {
            get => IsDir ? Directory.Exists(Path.Combine(FullName, "PDLC")) ? true : false : false;
        }
 
        public int CountDirs
        {
            get => _pathList == null ? 0 : _pathList.Select(x => x.IsDir).Count();
        }
 
        public int CountFiles
        {
            get => _pathList == null ? 0 : _pathList.Select(x => x.IsFile).Count();
        }
 
        public int CountData
        {
            get => _pathList == null ? 0 : _pathList.Count();
        }
    }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
[JsonIgnore]
public List<SFNPathInfo> GetProjectsFromPaths
{
    get
    {
        var list = new List<SFNPathInfo>();
 
        if (PathsProjects.Count > 0)
        {
            foreach (var project in PathsProjects)
            {
                var coredir = new DirectoryInfo(project.FullName);
                var dirs = coredir.GetDirectories();
                if (dirs.Length > 0)
                {
                    foreach (var dir in dirs)
                    {
                        var countFiles = dir.GetFiles($"*{RPGMakerParam.RPGMakerExt[(byte)Type]}").Length;
 
                        if (countFiles <= 0)
                            continue;
 
                        list.Add(new SFNPathInfo($"{project.Text} > {dir.Name}", dir.FullName));
                    }
                }
            }
        }
 
        return list;
    }
}
 
[JsonIgnore]
public List<SFNPathInfo> GetProjects
{
    get {
        var list = new List<SFNPathInfo>();
 
        if (Projects.Count > 0)
        {
            foreach (var dir in Projects)
            {
                var path = dir.DirectoryFullName;
                var countFiles = Directory.GetFiles(path, $"*{RPGMakerParam.RPGMakerExt[(byte)Type]}").Length;
 
                if (countFiles <= 0)
                    continue;
 
                list.Add(new SFNPathInfo(dir.Text, path));
            }
        }
 
        return list;
    }
}
 
[JsonIgnore]
public List<SFNPathInfo> AllDirProjects
{
    get
    {
        var list = new List<SFNPathInfo>();
 
        list.AddRange(GetProjectsFromPaths);
        list.AddRange(GetProjects);
 
        return list;
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
private void RefreshNodeProjects()
{
    IsRefreshProjects = true;
 
    var selObj = treeListViewProjectData.SelectedObject;
 
    treeListViewProjectData.Roots = null;
 
    if (CountEngineProjects > 0)
    {
        treeListViewProjectData.CanExpandGetter = obj => ((SFNPathInfo)obj).IsDir;
        treeListViewProjectData.ChildrenGetter = obj =>
        {
            try
            {
                return ((SFNPathInfo)obj).PathList;
            }
            catch (UnauthorizedAccessException ex)
            {
                // on error (e.g. restricted system dirs) show message box and collapse the subtree allowing the user to retry later
                // we cannot do this immediately in this getter because TreeListView will not react correctly and may remain in undefined state
                // so we use BeginInvoke to execute it a bit later on the UI thread
                BeginInvoke(new Action(() =>
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    treeListViewProjectData.Collapse(obj);
                }));
                return new List<SFNPathInfo>();
            }
        };
 
        treeListViewProjectData.ParentGetter = obj => ((SFNPathInfo)obj).Parent;
 
        treeListViewProjectData.Roots = SelectEngine.AllDirProjects;
 
        _tpcolName.ImageGetter = GetIconKey;
    }
    else
    {
        treeListViewProjectData.Roots = null;
    }
 
    treeListViewProjectData.SelectedObject = selObj;
    treeListViewProjectData.EnsureModelVisible(selObj);
 
    SelectFileInListViewProjectData();
 
    pnlInfo.ScrollToRight();
 
    IsRefreshProjects = false;
}
 
// загрузка иконки файла через WinApi и сохранение в imglstIcons
private string GetIconKey(SFNPathInfo fsItem)
{
    if (fsItem.IsDir)
        return "explorer.png";
    else
    {
        string key = $"F{fsItem.Ext}";
 
        if (File.Exists(fsItem.FullName))
        {
            AddImageToList(imageListProjects, key, System.Drawing.Icon.ExtractAssociatedIcon(fsItem.FullName));
            if (imageListProjects.Images.IndexOfKey(key) >= 0)
                return key;
            else
                return null;
        }
        else
        {
            var ind = imageListProjects.Images.IndexOfKey(key);
            if (ind >= 0)
                imageListProjects.Images.RemoveAt(ind);
            return null;
        }
    }
}
 
private void AddImageToList(ImageList imageList, string key, Icon icon)
{
    if (imageList.Images.IndexOfKey(key) < 0)
    {
        imageList.Images.Add(key, icon);
    }
}
 
private SFNPathInfo SelectedFile = null;
 
private Image GetImageSelectedFile()
{
    if (SelectedFile == null)
        return null;
 
    if (SelectedFile.IsDir)
    {
        var idx = imageListProjects.Images.IndexOfKey("explorer.png");
        return idx >= 0 ? imageListProjects.Images[idx] : null;
    }
    else if (SelectedFile.IsFile)
    {
        var idx = imageListProjects.Images.IndexOfKey($"F{SelectedFile.Ext}");
        return idx >= 0 ? imageListProjects.Images[idx] : null;
    }
    else return null;
}
 
private void SelectFileInListViewProjectData()
{
    SelectedFile = ((SFNPathInfo)treeListViewProjectData.SelectedObject);
    RefreshInfoSelectFile();
}
 
private void RefreshInfoSelectFile()
{
    if (SelectedFile != null)
    {
        if (!Directory.Exists(SelectedFile.FullName) && !File.Exists(SelectedFile.FullName))
            RefreshNodeProjects();
        else
        {
            toolStripButtonOpen.Image = GetImageSelectedFile();
            toolStripMenuItemDirFile.Enabled = true;
            showInExplorerToolStripMenuItem.Enabled = true;
            toolStripButtonOpen.Visible = toolStripButtonShowInExplorer.Visible = true;
            toolStripButtonOpenIn.Visible = (Gen.Settings.IsCountOtherProgramms && Gen.Settings.IsSelectOtherProgramm);
            labelSelectedProject.Text = Gen.GetTXSelectProject(SelectedFile.RootParent.Text);
            labelPathProject.Text = Gen.GetTXSelectProjectPath(SelectedFile.IsFile, SelectedFile.IsDir);
            copyLabelTextPathProject.Text = SelectedFile.FullName;
 
            toolStripMenuItemDirFile.Text = Gen.GetTXOpenDirFile(SelectedFile != null && SelectedFile.IsFile);
            toolStripMenuItemDirFile.Enabled = true;
        }
    }
    else
    {
        toolStripMenuItemDirFile.Enabled = false;
        showInExplorerToolStripMenuItem.Enabled = false;
        toolStripButtonOpen.Visible = toolStripButtonOpenIn.Visible = toolStripButtonShowInExplorer.Visible = false;
        labelSelectedProject.Text = Gen.GetTXSelectProject();
        labelPathProject.Text = Gen.GetTXSelectProjectPath(false, false);
        copyLabelTextPathProject.Text = "";
    }
 
    pnlInfo.ScrollToRight();
}
0
478 / 241 / 74
Регистрация: 25.05.2012
Сообщений: 1,139
Записей в блоге: 1
15.08.2024, 11:07
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Потому что по другому обновить данные нельзя.
можно обновить не отсоединяя если привязка будет не напрямую а через BindingSource например

Добавлено через 1 час 46 минут
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Нет. Не работает способ:
у меня работает в такой последовательности:
C#
1
2
3
treeListView.DeselectAll();
treeListView.SelectedObject = selectedObject;
treeListView.EnsureModelVisible(selectedObject);
Добавлено через 15 минут
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Потому что по другому обновить данные нельзя.
В общем только что проверил сам: у TreeListView для отображения изменений в коллекции совершенно точно не нужно отвязывать/привязывать ее или как-то еще манипулировать свойствами .Objects и .Roots . У TreeListview есть много методов (например, .RebuildAll(), .Refresh()), попробуйте какой вам подойдет.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
15.08.2024, 20:24  [ТС]
Цитата Сообщение от NewOrdered Посмотреть сообщение
В общем только что проверил сам: у TreeListView для отображения изменений в коллекции совершенно точно не нужно отвязывать/привязывать ее или как-то еще манипулировать свойствами .Objects и .Roots . У TreeListviewесть много методов (например, .RebuildAll(), .Refresh()), попробуйте какой вам подойдет.
Дело в том что свойство AllDirProjects не имеет функции set. Только get. Получение всех папок и файлов в виде дерева. Это присваивается в root и там и находится.
Если файл удален или переименован необходимо это всё дело пересобрать заново. Это гарантировано работает если к римеру пользователь удаляет или переименовывает файл через проводник. В данном конкретном случае treeListView необходим только для просмотра и открытия любого файла. Я ни собираюсь заменять проводник ибо там функционала в проводнике ногу сломить тащить весь в свою программу. Да и зачем если это в проводнике есть. У меня есть функция показа и открытия файла или папки в проводнике и этого достаточно.
Сам факт в том что если изменить файл через проводник или другим способом то единственный способ обновить данные это заново вызвать свойство AllDirProjects чего явно RebuildAll() делать не будут.
Так что мне кажется что когда файлами можно манипулировать извне (да банально проводником винды) то пересобрать это всё в нужно. В другой структуре мне джействительно пересобиравть не нужно и через treeListView делать именно управление древовидным классом но это речь про другое. В данном случае речь о файлах которые можно менять где угодно и должна быть возможность обновить это всё в своей программе с тем чтобы выделденный файл не сбрасывался или выделялось то где он лежал. Естественно пока это возможэно. Тоесть пока Parent не будет равен null.
В данном случае дело в том что treeListView отображает не все файлы на компьютере а только все файлы проектов.

Добавлено через 29 минут
Решил ради интереса проверить через RebuildAll(); не пересобирая каждый раз roots а только 1 раз при выборе движка.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
private void SelectTabEngine()
{
    if (Gen.Settings.IsCountEngines && Gen.Settings.IsSelectEngine)
    {
        SelectEngine = Gen.Settings.RPGMakers[Gen.Settings.SelectEngine];
        transferAnimationMVToMZToolStripMenuItem.Visible =
            (Gen.Settings.RPGMakers[Gen.Settings.SelectEngine].Type == RPGMakerType.RMMV || Gen.Settings.RPGMakers[Gen.Settings.SelectEngine].Type == RPGMakerType.RMMZ);
        CountEngineProjects = SelectEngine.CountProjects;
    }
    else
    {
        SelectEngine = null;
        CountEngineProjects = 0;
    }
 
    var typeEngine = SelectEngine != null ? SelectEngine.Type : RPGMakerType.None;
    showRMSettingsToolStripMenuItem.Text = Gen.GetTXShowRMSettings();
    labelSelectedEngine.Text = Gen.GetTXSelectEngine();
    toolStripSplitButton1.Text = Gen.GetTXLaunchEngine();
    toolStripMenuItemDirEngine.Text = Gen.GetTXOpenDirEngine();
    toolStripSplitButton1.Enabled = typeEngine != RPGMakerType.None;
    toolStripSplitButton1.Image = Gen.GetBitmapEngine(typeEngine, false, true);
    toolStripMenuItem1.Visible = SelectEngine != null && SelectEngine.CMDRun.Length > 0;
    if (!toolStripMenuItem1.Visible)
        toolStripMenuItem1.Checked = false;
    imgLogoEngine.Image = Gen.GetBitmapEngine(typeEngine, true, false);
 
    QuickRunProjectRefresh();
 
    InitNodeProjects();
}
 
private void QuickRunProjectRefresh()
{
    foreach (var item in toolStripMenuItems)
    {
        toolStripSplitButton1.DropDownItems.Remove(item);
    }
 
    toolStripMenuItems.Clear();
 
    if (!Gen.Settings.IsSelectEngine) return;
 
    if (SelectEngine.Projects.Count <= 0) return;
 
    foreach (var item in SelectEngine.Projects)
    {
        toolStripMenuItems.Add(new ToolStripMenuItem($"{item.Text}", null, toolStripMenuItemQuickRunProject_Click)
        {
            Tag = item.FullName
        });
    }
 
    toolStripSplitButton1.DropDownItems.AddRange(toolStripMenuItems.ToArray());
}
 
#endregion
 
#region Проекты
 
private readonly TypedObjectListView<SFNPathInfo> _tptvFilesystem;
private readonly TypedColumn<SFNPathInfo> _tpcolName;
 
//private ShellContextMenu ctxMnu = new ShellContextMenu();
 
private bool IsRefreshProjects = false;
 
private void InitNodeProjects()
{
    if (CountEngineProjects > 0)
    {
 
        treeListViewProjectData.CanExpandGetter = obj => ((SFNPathInfo)obj).IsDir;
        treeListViewProjectData.ChildrenGetter = obj =>
        {
            try
            {
                return ((SFNPathInfo)obj).PathList;
            }
            catch (UnauthorizedAccessException ex)
            {
                // on error (e.g. restricted system dirs) show message box and collapse the subtree allowing the user to retry later
                // we cannot do this immediately in this getter because TreeListView will not react correctly and may remain in undefined state
                // so we use BeginInvoke to execute it a bit later on the UI thread
                BeginInvoke(new Action(() =>
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    treeListViewProjectData.Collapse(obj);
                }));
                return new BindingList<SFNPathInfo>();
            }
        };
 
        treeListViewProjectData.ParentGetter = obj => ((SFNPathInfo)obj).Parent;
        treeListViewProjectData.Roots = SelectEngine.AllDirProjects;
        _tpcolName.ImageGetter = GetIconKey;
 
        RefreshNodeProjects();
    }
    else
    {
        treeListViewProjectData.Roots = null;
    }
}
 
private void RefreshNodeProjects()
{
    IsRefreshProjects = true;
 
    treeListViewProjectData.RebuildAll(true);
 
    SelectFileInListViewProjectData();
 
    pnlInfo.ScrollToRight();
 
    IsRefreshProjects = false;
}
 
// загрузка иконки файла через WinApi и сохранение в imglstIcons
private string GetIconKey(SFNPathInfo fsItem)
{
    if (fsItem.IsDir)
        return "explorer.png";
    else
    {
        string key = $"F{fsItem.Ext}";
 
        if (File.Exists(fsItem.FullName))
        {
            AddImageToList(imageListProjects, key, System.Drawing.Icon.ExtractAssociatedIcon(fsItem.FullName));
            if (imageListProjects.Images.IndexOfKey(key) >= 0)
                return key;
            else
                return null;
        }
        else
        {
            var ind = imageListProjects.Images.IndexOfKey(key);
            if (ind >= 0)
                imageListProjects.Images.RemoveAt(ind);
            return null;
        }
    }
}
 
private void AddImageToList(ImageList imageList, string key, Icon icon)
{
    if (imageList.Images.IndexOfKey(key) < 0)
    {
        imageList.Images.Add(key, icon);
    }
}
 
private SFNPathInfo SelectedFile = null;
 
private Image GetImageSelectedFile()
{
    if (SelectedFile == null)
        return null;
 
    if (SelectedFile.IsDir)
    {
        var idx = imageListProjects.Images.IndexOfKey("explorer.png");
        return idx >= 0 ? imageListProjects.Images[idx] : null;
    }
    else if (SelectedFile.IsFile)
    {
        var idx = imageListProjects.Images.IndexOfKey($"F{SelectedFile.Ext}");
        return idx >= 0 ? imageListProjects.Images[idx] : null;
    }
    else return null;
}
 
private void SelectFileInListViewProjectData()
{
    SelectedFile = ((SFNPathInfo)treeListViewProjectData.SelectedObject);
    RefreshInfoSelectFile();
}
 
private void RefreshInfoSelectFile()
{
    if (SelectedFile != null)
    {
        if (!Directory.Exists(SelectedFile.FullName) && !File.Exists(SelectedFile.FullName))
            RefreshNodeProjects();
        else
        {
            toolStripButtonOpen.Image = GetImageSelectedFile();
            toolStripMenuItemDirFile.Enabled = true;
            showInExplorerToolStripMenuItem.Enabled = true;
            toolStripButtonOpen.Visible = toolStripButtonShowInExplorer.Visible = true;
            toolStripButtonOpenIn.Visible = (Gen.Settings.IsCountOtherProgramms && Gen.Settings.IsSelectOtherProgramm);
            labelSelectedProject.Text = Gen.GetTXSelectProject(SelectedFile.RootParent.Text);
            labelPathProject.Text = Gen.GetTXSelectProjectPath(SelectedFile.IsFile, SelectedFile.IsDir);
            copyLabelTextPathProject.Text = SelectedFile.FullName;
 
            toolStripMenuItemDirFile.Text = Gen.GetTXOpenDirFile(SelectedFile != null && SelectedFile.IsFile);
            toolStripMenuItemDirFile.Enabled = true;
        }
    }
    else
    {
        toolStripMenuItemDirFile.Enabled = false;
        showInExplorerToolStripMenuItem.Enabled = false;
        toolStripButtonOpen.Visible = toolStripButtonOpenIn.Visible = toolStripButtonShowInExplorer.Visible = false;
        labelSelectedProject.Text = Gen.GetTXSelectProject();
        labelPathProject.Text = Gen.GetTXSelectProjectPath(false, false);
        copyLabelTextPathProject.Text = "";
    }
 
    pnlInfo.ScrollToRight();
}
Ну как итог если удалить файл или папку и поробовать её выбрать в treeListView то она при вызове RebuldAll не пропадает и возникает ошибка попытки взаимодействия с тем чего нет.

Добавлено через 12 минут
Так что без обновления Roots тут никуда не деться. Но в таком варианте действительно выделение не пропадает. Но а толку если обновление и нужно из расчёта того что изменения с файлами были.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.08.2024, 20:24

Отображение в ListBox списка найденных файлов и папок
Доброго времени суток. Столкнулся с таким вот отображением(рис.1). если поставить в параметр DisplayMemberPath=&quot;Name&quot;, то...

Отображение списка текстовых файлов внутри программы
Всем привет. Нужна помощь. В делфи не силен (полный 0). Хочу сделать программу которая будет выдавать список текстовых документов и...

Создание папок с несколькими вложенными папками по названию в ячейки
Добрый день. Мне нужна помощь в создании макроса. Исходные данные такие: Есть несколько столбиков. В первом столбике прописаны...

Разработка подсистемы управления файлами со способом физической организации файла в виде связанного списка блоков
Помогите пожалуйста написать код, на Python, на тему &quot;Разработка подсистемы управления файлами со способом физической организации файла в...

Скопировать из разных папок в одну с под папками и разными расширениями
foreach (var file in Directory.GetFiles(InitPath(), &quot;*.&quot;)) { File.Copy(file, Path.Combine(PathHome, Path.GetFileName(file))); } ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
Знание — сила: Доктрина интенциональности знаний против массовых профанаций
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302 Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
SUNO Ai - Река Без Дна
zorxor 31.07.2026
Автор стихотворения - астрофизик Марина Катыс Ссылка на сгенерированную музыкальную композицию: https:/ / suno. com/ song/ 6f6e5464-b290-4650-be6c-44c85f8d8013 Я говорю, что Время- как вода течет. . .
Из невошедшего на форум (диалог с ИИ-гугла)
zorxor 29.07.2026
А вот, что интересно, сказал мне ИИ-гугла: Этот текст — эмоциональный пост пользователя под ником zorxor на интернет-форуме (вероятно, посвященном мистике, непознанному или альтернативной науке). . . .
Был праздник вчера, а я и не знал.
kumehtar 28.07.2026
27. 07. 2026г. Intel Core 2 Duo исполнилось 20 лет Салют, шампанское, овации! :drink:
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр. Дословно, отклонённая. . .
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru