• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

ファイル整理用ツールのPrism+WPFサンプル実装


コミットメタ情報

リビジョン96c592e9a9cd78d64c1098cf1c7702936f101d32 (tree)
日時2022-07-30 21:03:34
作者yoshy <yoshy.org.bitbucket@gz.j...>
コミッターyoshy

ログメッセージ

[UPD] ドロップ対象のパスがファイルリストのドロップ先配下に含まれるパスの場合にドロップ不可にする処理を追加
[MOD] タブ・フォルダーツリーViewModelのマップをツリーナビゲーションViewModelから切り出し
[FIX] ドロップ対象のパスがドロップ先配下に含まれるパスかどうかの判定ロジックに不具合があったため修正

変更サマリ

差分

--- a/FolderCategorizer2.01Domain/Service/Dto/FileSystemSourceTargetEntry.cs
+++ b/FolderCategorizer2.01Domain/Service/Dto/FileSystemSourceTargetEntry.cs
@@ -17,5 +17,18 @@ namespace FolderCategorizer2.Domain.Service.Dto
1717 : this(target.TreeID, target, source)
1818 {
1919 }
20+
21+ public static IEnumerable<FileSystemSourceTargetEntry> Join(
22+ IEnumerable<FileSystemTargetFolder> targetFolders,
23+ IEnumerable<FileSystemSourceFiles> sourceFilesList)
24+ {
25+ IEnumerable<FileSystemSourceTargetEntry> sourceTargetEntries = targetFolders.Join(
26+ sourceFilesList,
27+ target => target.TreeID,
28+ source => source.TreeID,
29+ (target, source) => new FileSystemSourceTargetEntry(target, source));
30+
31+ return sourceTargetEntries;
32+ }
2033 }
2134 }
--- a/FolderCategorizer2.02UseCase/FileSystemOperation/Interactor/FileSystemCopyOperationInteractor.cs
+++ b/FolderCategorizer2.02UseCase/FileSystemOperation/Interactor/FileSystemCopyOperationInteractor.cs
@@ -70,11 +70,8 @@ namespace FolderCategorizer2.UseCase.FileSystemOperation.Interactor
7070 return UseCaseResponse.Abort<FileSystemCopyOperationResponse>(msg);
7171 }
7272
73- IEnumerable<FileSystemSourceTargetEntry> sourceTargetEntries = targetFolders.Join(
74- sourceFilesList,
75- target => target.TreeID,
76- source => source.TreeID,
77- (target, source) => new FileSystemSourceTargetEntry(target, source));
73+ IEnumerable<FileSystemSourceTargetEntry> sourceTargetEntries =
74+ FileSystemSourceTargetEntry.Join(targetFolders, sourceFilesList);
7875
7976 {
8077 string msg = "【仮】コピーしてもよろしいですか";
--- a/FolderCategorizer2.02UseCase/FileSystemOperation/Interactor/FileSystemMoveOperationInteractor.cs
+++ b/FolderCategorizer2.02UseCase/FileSystemOperation/Interactor/FileSystemMoveOperationInteractor.cs
@@ -70,11 +70,8 @@ namespace FolderCategorizer2.UseCase.FileSystemOperation.Interactor
7070 return UseCaseResponse.Abort<FileSystemMoveOperationResponse>(msg);
7171 }
7272
73- IEnumerable<FileSystemSourceTargetEntry> sourceTargetEntries = targetFolders.Join(
74- sourceFilesList,
75- target => target.TreeID,
76- source => source.TreeID,
77- (target, source) => new FileSystemSourceTargetEntry(target, source));
73+ IEnumerable<FileSystemSourceTargetEntry> sourceTargetEntries =
74+ FileSystemSourceTargetEntry.Join(targetFolders, sourceFilesList);
7875
7976 {
8077 string msg = "【仮】移動してもよろしいですか";
--- a/FolderCategorizer2.03Adaptor/AdaptorModule.cs
+++ b/FolderCategorizer2.03Adaptor/AdaptorModule.cs
@@ -60,14 +60,17 @@ namespace FolderCategorizer2.Adaptor
6060 containerRegistry.RegisterSingleton<IMainWindowViewModel, MainWindowViewModel>();
6161 containerRegistry.RegisterSingleton<IStatusBarViewModel, StatusBarViewModel>();
6262
63+ containerRegistry.RegisterSingleton<ITreeNavigationViewModel, TreeNavigationViewModel>();
64+
6365 containerRegistry.RegisterSingleton<IFolderTreeTabViewModel, FolderTreeTabViewModel>();
6466 containerRegistry.Register<IFolderTreeViewModel, FolderTreeViewModel>();
65- containerRegistry.RegisterSingleton<ITreeNavigationViewModel, TreeNavigationViewModel>();
6667
6768 containerRegistry.RegisterSingleton<IFileListViewModel, FileListViewModel>();
6869
6970 containerRegistry.RegisterSingleton<IDragRangeSelectorViewModel, DragRangeSelectorViewModel>();
7071
72+ containerRegistry.RegisterSingleton<IInterViewModelStore, InterViewModelStore>();
73+
7174 ///
7275 /// Translators
7376 ///
--- a/FolderCategorizer2.03Adaptor/Boundary/ViewModel/Child/IFileListRowViewModel.cs
+++ b/FolderCategorizer2.03Adaptor/Boundary/ViewModel/Child/IFileListRowViewModel.cs
@@ -27,6 +27,6 @@ namespace FolderCategorizer2.Adaptor.Boundary.ViewModel.Child
2727
2828 void NotifyCopyFileListDropped(DnDSourceFileInfo draggedFileList);
2929 void NotifyMoveFileListDropped(DnDSourceFileInfo draggedFileList);
30- bool CheckFileListDragOver(DnDSourceFileInfo draggedFileList);
30+ bool IsDroppableTarget(DnDSourceFileInfo draggedFileList);
3131 }
3232 }
\ No newline at end of file
--- a/FolderCategorizer2.03Adaptor/Boundary/ViewModel/Child/IFolderTreeNodeViewModel.cs
+++ b/FolderCategorizer2.03Adaptor/Boundary/ViewModel/Child/IFolderTreeNodeViewModel.cs
@@ -22,6 +22,6 @@ namespace FolderCategorizer2.Adaptor.Boundary.ViewModel.Child
2222
2323 void NotifyCopyFileListDropped(DnDSourceFileInfo draggedFileList);
2424 void NotifyMoveFileListDropped(DnDSourceFileInfo draggedFileList);
25- bool CheckFileListDragOver(DnDSourceFileInfo draggedFileList);
25+ bool IsDroppableTarget(DnDSourceFileInfo draggedFileList);
2626 }
2727 }
\ No newline at end of file
--- a/FolderCategorizer2.03Adaptor/Boundary/ViewModel/IFileListViewModel.cs
+++ b/FolderCategorizer2.03Adaptor/Boundary/ViewModel/IFileListViewModel.cs
@@ -24,5 +24,6 @@ namespace FolderCategorizer2.Adaptor.Boundary.ViewModel
2424
2525 IList<DnDSourceFileImageEntry> CreateDraggedImages();
2626 IList<FileSystemSourceFiles> CreateSelectedSourceFilesList();
27+ bool IsDroppableTarget(IEnumerable<FileSystemSourceTargetEntry> sourceTargetEntries);
2728 }
2829 }
\ No newline at end of file
--- a/FolderCategorizer2.03Adaptor/Boundary/ViewModel/ITreeNavigationViewModel.cs
+++ b/FolderCategorizer2.03Adaptor/Boundary/ViewModel/ITreeNavigationViewModel.cs
@@ -1,9 +1,9 @@
11 using FolderCategorizer2.Adaptor.Boundary.Controller;
2+using FolderCategorizer2.Adaptor.Gateway.ViewModel;
23 using FolderCategorizer2.Adaptor.Translator.Event.Converter;
34 using FolderCategorizer2.Domain.Model.Const;
45 using FolderCategorizer2.Domain.Model.Entity;
56 using Reactive.Bindings;
6-using System.Collections.Generic;
77
88 namespace FolderCategorizer2.Adaptor.Boundary.ViewModel
99 {
@@ -17,14 +17,12 @@ namespace FolderCategorizer2.Adaptor.Boundary.ViewModel
1717 ReactiveCommand<RoutedNamedElementEventDto> CommandSelectTargetPath { get; }
1818
1919 IAppWindowController WindowController { get; }
20+ IInterViewModelStore InterVmStore { get; }
2021
2122 void OnNotifyTreeTabChanged(string id);
2223 void NotifyTreeViewNavigated(IFolderTreeViewModel treeVm);
2324 void RefreshFolderTree(string treeId, FolderTree tree);
2425 void NotifyExpandedFolderChanged(string regionName, string relativePath, RecursiveSearchLevel level, bool isExpanded);
2526 void NotifySelectedFolderChanged(string regionName, string relativePath);
26-
27- IEnumerable<IFolderTreeViewModel> FindTreeViewModelsByTabId(string tabId);
28- IEnumerable<IFolderTreeViewModel> GetTreeViewModels();
2927 }
3028 }
\ No newline at end of file
--- a/FolderCategorizer2.03Adaptor/Gateway/ViewModel/Child/FileListRowViewModel.FileListDropTarget.cs
+++ b/FolderCategorizer2.03Adaptor/Gateway/ViewModel/Child/FileListRowViewModel.FileListDropTarget.cs
@@ -33,7 +33,7 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel.Child
3333
3434 IFileListRowViewModel targetVm = (IFileListRowViewModel)targetItem.DataContext;
3535
36- if (targetVm.CheckFileListDragOver(draggedFileList))
36+ if (targetVm.IsDroppableTarget(draggedFileList))
3737 {
3838 dropInfo.Effects = DropInfoKeyStatesToEffects.Convert(dropInfo.KeyStates);
3939 }
--- a/FolderCategorizer2.03Adaptor/Gateway/ViewModel/Child/FileListRowViewModel.cs
+++ b/FolderCategorizer2.03Adaptor/Gateway/ViewModel/Child/FileListRowViewModel.cs
@@ -84,18 +84,25 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel.Child
8484
8585 #region event handler
8686
87- public bool CheckFileListDragOver(DnDSourceFileInfo draggedFileList)
87+ public bool IsDroppableTarget(DnDSourceFileInfo draggedFileList)
8888 {
8989 // TODO LINKの場合
90- return this.Type.Value == FileEntryType.FOLDER;
90+ if (this.Type.Value != FileEntryType.FOLDER)
91+ {
92+ return false;
93+ }
94+
95+ IEnumerable<FileSystemTargetFolder> targetFolders = CreateTargetFolders();
96+
97+ IEnumerable<FileSystemSourceTargetEntry> sourceTargetEntries =
98+ FileSystemSourceTargetEntry.Join(targetFolders, draggedFileList.SourceFilesList);
99+
100+ return this.ParentVm.IsDroppableTarget(sourceTargetEntries);
91101 }
92102
93103 public void NotifyCopyFileListDropped(DnDSourceFileInfo draggedFileList)
94104 {
95- // TODO LINKの場合
96- IEnumerable<FileSystemTargetFolder> targets = this.Source.Sources
97- .Where(row => row.Type.Value == FileEntryType.FOLDER)
98- .Select(row => new FileSystemTargetFolder(row.Parent, this.Name.Value));
105+ IEnumerable<FileSystemTargetFolder> targets = CreateTargetFolders();
99106
100107 foreach (FileSystemTargetFolder target in targets)
101108 {
@@ -111,6 +118,14 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel.Child
111118 _ = this.ParentVm.WindowController.Execute(req);
112119 }
113120
121+ private IEnumerable<FileSystemTargetFolder> CreateTargetFolders()
122+ {
123+ // TODO LINKの場合
124+ return this.Source.Sources
125+ .Where(row => row.Type.Value == FileEntryType.FOLDER)
126+ .Select(row => new FileSystemTargetFolder(row.Parent, this.Name.Value));
127+ }
128+
114129 public void NotifyMoveFileListDropped(DnDSourceFileInfo draggedFileList)
115130 {
116131 // TODO LINKの場合
--- a/FolderCategorizer2.03Adaptor/Gateway/ViewModel/Child/FolderTreeNodeViewModel.FolderTreeDragSource.cs
+++ b/FolderCategorizer2.03Adaptor/Gateway/ViewModel/Child/FolderTreeNodeViewModel.FolderTreeDragSource.cs
@@ -1,15 +1,12 @@
11 using FolderCategorizer2.Adaptor.Boundary.ViewModel;
22 using FolderCategorizer2.Adaptor.Boundary.ViewModel.Child;
33 using FolderCategorizer2.Adaptor.Gateway.ViewModel.Dto;
4-using FolderCategorizer2.Adaptor.Translator.Converter;
54 using FolderCategorizer2.Domain.Service.Dto;
65 using GongSolutions.Wpf.DragDrop;
76 using NLog;
87 using System;
98 using System.Collections.Generic;
10-using System.Runtime.InteropServices;
119 using System.Windows;
12-using System.Windows.Media;
1310
1411 namespace FolderCategorizer2.Adaptor.Gateway.ViewModel.Child
1512 {
@@ -41,9 +38,11 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel.Child
4138
4239 IList<FileSystemSourceFiles> sourceFilesList = new List<FileSystemSourceFiles>();
4340
44- foreach (IFolderTreeViewModel vm in treeNaviVm.FindTreeViewModelsByTabId(treeVm.TabID))
41+ foreach (IFolderTreeViewModel vm
42+ in treeNaviVm.InterVmStore.FindTreeViewModelsByTabId(treeVm.TabID))
4543 {
46- sourceFilesList.Add(new FileSystemSourceFiles(vm.TreeID, vm.TargetPath, new string[] { item.Text.Value }));
44+ sourceFilesList.Add(new FileSystemSourceFiles(
45+ vm.TreeID, vm.TargetPath, new string[] { item.Text.Value }));
4746 }
4847
4948 dragInfo.Data = new DnDSourceFileInfo(draggedImages, sourceFilesList);
--- a/FolderCategorizer2.03Adaptor/Gateway/ViewModel/Child/FolderTreeNodeViewModel.FolderTreeDropTarget.cs
+++ b/FolderCategorizer2.03Adaptor/Gateway/ViewModel/Child/FolderTreeNodeViewModel.FolderTreeDropTarget.cs
@@ -33,7 +33,7 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel.Child
3333
3434 IFolderTreeNodeViewModel targetVm = (IFolderTreeNodeViewModel)targetItem.DataContext;
3535
36- if (targetVm.CheckFileListDragOver(draggedFileList))
36+ if (targetVm.IsDroppableTarget(draggedFileList))
3737 {
3838 dropInfo.Effects = DropInfoKeyStatesToEffects.Convert(dropInfo.KeyStates);
3939 }
--- a/FolderCategorizer2.03Adaptor/Gateway/ViewModel/Child/FolderTreeNodeViewModel.cs
+++ b/FolderCategorizer2.03Adaptor/Gateway/ViewModel/Child/FolderTreeNodeViewModel.cs
@@ -99,8 +99,10 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel.Child
9999 }
100100 }
101101
102- public bool CheckFileListDragOver(DnDSourceFileInfo draggedFileList)
102+ public bool IsDroppableTarget(DnDSourceFileInfo draggedFileList)
103103 {
104+ FileSystemTargetFolder targetFolder = new(this.ParentVm.TreeID, this.AbsolutePath);
105+
104106 FileSystemSourceFiles sourceFiles = draggedFileList.SourceFilesList
105107 .Where(list => list.TreeID == this.ParentVm.TreeID).FirstOrDefault();
106108
@@ -109,27 +111,7 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel.Child
109111 return false;
110112 }
111113
112- string targetFolderFullPath = this.AbsolutePath;
113- string sourceFolderFullPath = sourceFiles.Path;
114-
115- //logger.Trace("CheckFileListDragOver: target {0}, source {1}", targetFolderFullPath, sourceFolderFullPath);
116-
117- if (targetFolderFullPath == sourceFolderFullPath)
118- {
119- return false;
120- }
121-
122- foreach (var name in sourceFiles.Names)
123- {
124- string sourceFullPath = PathHelper.CreateCanonicalPath(sourceFolderFullPath, name);
125-
126- if (PathHelper.IsSameOrChild(targetFolderFullPath, sourceFullPath))
127- {
128- return false;
129- }
130- }
131-
132- return true;
114+ return DroppableTargetHelper.IsDroppableTarget(targetFolder, sourceFiles);
133115 }
134116
135117 public void NotifyCopyFileListDropped(DnDSourceFileInfo draggedFileList)
@@ -138,7 +120,7 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel.Child
138120
139121 logger.Trace("FolderTreeNodeViewModel: relativePath {0}", relativePath);
140122
141- IEnumerable<IFolderTreeViewModel> vms = this.ParentVm.ParentVm.GetTreeViewModels();
123+ IEnumerable<IFolderTreeViewModel> vms = this.ParentVm.ParentVm.InterVmStore.GetTreeViewModels();
142124
143125 IEnumerable<FileSystemTargetFolder> targets = vms.Select(vm => vm.Source)
144126 .Where(src => src != null)
@@ -165,7 +147,7 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel.Child
165147
166148 logger.Trace("FolderTreeNodeViewModel: relativePath {0}", relativePath);
167149
168- IEnumerable<IFolderTreeViewModel> vms = this.ParentVm.ParentVm.GetTreeViewModels();
150+ IEnumerable<IFolderTreeViewModel> vms = this.ParentVm.ParentVm.InterVmStore.GetTreeViewModels();
169151
170152 IEnumerable<FileSystemTargetFolder> targets = vms.Select(vm => vm.Source)
171153 .Where(src => src != null)
--- /dev/null
+++ b/FolderCategorizer2.03Adaptor/Gateway/ViewModel/DroppableTargetHelper.cs
@@ -0,0 +1,43 @@
1+using CleanAuLait.Core.IO;
2+using FolderCategorizer2.Domain.Service.Dto;
3+using NLog;
4+
5+namespace FolderCategorizer2.Adaptor.Gateway.ViewModel
6+{
7+ internal static class DroppableTargetHelper
8+ {
9+ private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
10+
11+ public static bool IsDroppableTarget(FileSystemSourceTargetEntry sourceTargetEntry)
12+ {
13+ return IsDroppableTarget(sourceTargetEntry.TargetFolder, sourceTargetEntry.SourceFiles);
14+ }
15+
16+ public static bool IsDroppableTarget(
17+ FileSystemTargetFolder targetFolder, FileSystemSourceFiles sourceFiles)
18+ {
19+ string targetFolderFullPath = targetFolder.Path;
20+ string sourceFolderFullPath = sourceFiles.Path;
21+
22+ //logger.Trace("CheckFileListDragOver: target {0}, source {1}", targetFolderFullPath, sourceFolderFullPath);
23+
24+ if (targetFolderFullPath == sourceFolderFullPath)
25+ {
26+ return false;
27+ }
28+
29+ foreach (var name in sourceFiles.Names)
30+ {
31+ string sourceFullPath = PathHelper.CreateCanonicalPath(sourceFolderFullPath, name);
32+
33+ if (PathHelper.IsSameOrChild(sourceFullPath, targetFolder.Path))
34+ {
35+ return false;
36+ }
37+ }
38+
39+ return true;
40+ }
41+
42+ }
43+}
--- a/FolderCategorizer2.03Adaptor/Gateway/ViewModel/FileListViewModel.cs
+++ b/FolderCategorizer2.03Adaptor/Gateway/ViewModel/FileListViewModel.cs
@@ -133,6 +133,20 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel
133133 return sourceFilesList;
134134 }
135135
136+ public bool IsDroppableTarget(
137+ IEnumerable<FileSystemSourceTargetEntry> sourceTargetEntries)
138+ {
139+ foreach (var entry in sourceTargetEntries)
140+ {
141+ if (!DroppableTargetHelper.IsDroppableTarget(entry))
142+ {
143+ return false;
144+ }
145+ }
146+
147+ return true;
148+ }
149+
136150 #endregion
137151 }
138152 }
--- /dev/null
+++ b/FolderCategorizer2.03Adaptor/Gateway/ViewModel/IInterViewModelStore.cs
@@ -0,0 +1,14 @@
1+using FolderCategorizer2.Adaptor.Boundary.ViewModel;
2+using System.Collections.Generic;
3+
4+namespace FolderCategorizer2.Adaptor.Gateway.ViewModel
5+{
6+ public interface IInterViewModelStore
7+ {
8+ void AddTabIdTreeIdViewModelMap(IFolderTreeViewModel treeVm);
9+ void AddTreeIdViewModelMap(IFolderTreeViewModel treeVm);
10+ IFolderTreeViewModel FindTreeIdViewModelMapByTreeId(string treeId);
11+ IEnumerable<IFolderTreeViewModel> FindTreeViewModelsByTabId(string tabId);
12+ IEnumerable<IFolderTreeViewModel> GetTreeViewModels();
13+ }
14+}
\ No newline at end of file
--- /dev/null
+++ b/FolderCategorizer2.03Adaptor/Gateway/ViewModel/InterViewModelStore.cs
@@ -0,0 +1,81 @@
1+using CleanAuLait.Core.Log;
2+using FolderCategorizer2.Adaptor.Boundary.ViewModel;
3+using NLog;
4+using System;
5+using System.Collections.Generic;
6+using System.Linq;
7+
8+namespace FolderCategorizer2.Adaptor.Gateway.ViewModel
9+{
10+ internal class InterViewModelStore : IInterViewModelStore
11+ {
12+ private static readonly ILogger logger = LogManager.GetCurrentClassLogger();
13+
14+ private readonly IDictionary<string, IFolderTreeViewModel> treeIdVmMap =
15+ new Dictionary<string, IFolderTreeViewModel>();
16+
17+ private readonly IDictionary<string, IDictionary<string, IFolderTreeViewModel>> tabIdVmMap =
18+ new Dictionary<string, IDictionary<string, IFolderTreeViewModel>>();
19+
20+ public void AddTreeIdViewModelMap(IFolderTreeViewModel treeVm)
21+ {
22+ string treeId = treeVm.TreeID;
23+
24+ if (!this.treeIdVmMap.ContainsKey(treeId))
25+ {
26+ this.treeIdVmMap.Add(treeId, treeVm);
27+
28+ logger.Trace("AddTreeIdViewModelMap: tree {0} -> VM[{1}] added.",
29+ treeId, treeVm.ToHashString());
30+
31+ }
32+ }
33+
34+ public void AddTabIdTreeIdViewModelMap(IFolderTreeViewModel treeVm)
35+ {
36+ string tabId = treeVm.TabID;
37+ string treeId = treeVm.TreeID;
38+
39+ if (!this.tabIdVmMap.TryGetValue(
40+ tabId, out IDictionary<string, IFolderTreeViewModel> tabIdTreeIdVmMap))
41+ {
42+ tabIdTreeIdVmMap = new SortedDictionary<string, IFolderTreeViewModel>();
43+ this.tabIdVmMap.Add(tabId, tabIdTreeIdVmMap);
44+ }
45+
46+ if (!tabIdTreeIdVmMap.ContainsKey(treeId))
47+ {
48+ tabIdTreeIdVmMap.Add(treeId, treeVm);
49+
50+ logger.Trace("AddTabIdTreeIdViewModelMap: tab {0} -> tree {1} -> VM[{2}] added.",
51+ tabId, treeId, treeVm.ToHashString());
52+ }
53+ }
54+ public IEnumerable<IFolderTreeViewModel> FindTreeViewModelsByTabId(string tabId)
55+ {
56+ if (!this.tabIdVmMap.TryGetValue(
57+ tabId, out IDictionary<string, IFolderTreeViewModel> tabIdTreeIdVmMap))
58+ {
59+ throw new ArgumentException("invalid tab id");
60+ }
61+
62+ return tabIdTreeIdVmMap.Select(x => x.Value);
63+ }
64+
65+ public IFolderTreeViewModel FindTreeIdViewModelMapByTreeId(string treeId)
66+ {
67+ if (!this.treeIdVmMap.TryGetValue(treeId, out IFolderTreeViewModel vm))
68+ {
69+ throw new ArgumentException("invalid tree id");
70+ }
71+ return vm;
72+ }
73+
74+ public IEnumerable<IFolderTreeViewModel> GetTreeViewModels()
75+ {
76+ return this.treeIdVmMap.Values;
77+ }
78+
79+
80+ }
81+}
--- a/FolderCategorizer2.03Adaptor/Gateway/ViewModel/TreeNavigationViewModel.cs
+++ b/FolderCategorizer2.03Adaptor/Gateway/ViewModel/TreeNavigationViewModel.cs
@@ -1,7 +1,6 @@
11 using CleanAuLait.Adaptor.Boundary.Gateway.UI.Dialog.Shell;
22 using CleanAuLait.Adaptor.Gateway.UI.Dialog.Shell.Parameters;
33 using CleanAuLait.Core.IO;
4-using CleanAuLait.Core.Log;
54 using FolderCategorizer2.Adaptor.Boundary.Controller;
65 using FolderCategorizer2.Adaptor.Boundary.ViewModel;
76 using FolderCategorizer2.Adaptor.Translator;
@@ -16,7 +15,6 @@ using Prism.Regions;
1615 using Reactive.Bindings;
1716 using Reactive.Bindings.Extensions;
1817 using System;
19-using System.Collections.Generic;
2018 using System.ComponentModel;
2119 using System.Linq;
2220 using System.Reactive.Disposables;
@@ -55,23 +53,20 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel
5553 public ReactiveCommand<RoutedNamedElementEventDto> CommandSelectTargetPath { get; }
5654
5755 public IAppWindowController WindowController { get; }
56+ public IInterViewModelStore InterVmStore { get; }
5857
5958 private readonly IRegionManager regionManager;
6059 private readonly IFolderTreeIdTranslator idTranslator;
61-
6260 private readonly ICommonFolderDialogProxy folderDlg;
6361
64- private readonly IDictionary<string, IFolderTreeViewModel> treeIdVmMap =
65- new Dictionary<string, IFolderTreeViewModel>();
66-
67- private readonly IDictionary<string, IDictionary<string, IFolderTreeViewModel>> tabIdVmMap =
68- new Dictionary<string, IDictionary<string, IFolderTreeViewModel>>();
69-
7062 private readonly CompositeDisposable disposables = new();
7163
7264 public TreeNavigationViewModel(
73- IRegionManager regionManager, IAppWindowController windowController,
74- IFolderTreeTabViewModel tabVm, IFolderTreeIdTranslator idTranslator,
65+ IAppWindowController windowController,
66+ IRegionManager regionManager,
67+ IInterViewModelStore interVmStore,
68+ IFolderTreeTabViewModel tabVm,
69+ IFolderTreeIdTranslator idTranslator,
7570 ICommonFolderDialogProxy folderDlg)
7671 {
7772 this.WindowController = windowController;
@@ -79,6 +74,8 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel
7974 this.regionManager = regionManager;
8075 this.idTranslator = idTranslator;
8176
77+ this.InterVmStore = interVmStore;
78+
8279 this.folderDlg = folderDlg;
8380
8481 this.TargetPath1 = new ReactivePropertySlim<string>().AddTo(disposables);
@@ -263,80 +260,20 @@ namespace FolderCategorizer2.Adaptor.Gateway.ViewModel
263260 return;
264261 }
265262
266- AddTreeIdViewModelMap(treeVm);
267- AddTabIdTreeIdViewModelMap(treeVm);
263+ this.InterVmStore.AddTreeIdViewModelMap(treeVm);
264+ this.InterVmStore.AddTabIdTreeIdViewModelMap(treeVm);
268265
269266 NotifySelectedFolderChanged(treeVm.RegionName, treeVm.SelectedPath);
270267 }
271268
272- private void AddTreeIdViewModelMap(IFolderTreeViewModel treeVm)
273- {
274- string treeId = treeVm.TreeID;
275-
276- if (!this.treeIdVmMap.ContainsKey(treeId))
277- {
278- this.treeIdVmMap.Add(treeId, treeVm);
279-
280- logger.Trace("AddTreeIdViewModelMap: tree {0} -> VM[{1}] added.",
281- treeId, treeVm.ToHashString());
282-
283- }
284- }
285-
286- private void AddTabIdTreeIdViewModelMap(IFolderTreeViewModel treeVm)
287- {
288- string tabId = treeVm.TabID;
289- string treeId = treeVm.TreeID;
290-
291- if (!this.tabIdVmMap.TryGetValue(
292- tabId, out IDictionary<string, IFolderTreeViewModel> tabIdTreeIdVmMap))
293- {
294- tabIdTreeIdVmMap = new SortedDictionary<string, IFolderTreeViewModel>();
295- this.tabIdVmMap.Add(tabId, tabIdTreeIdVmMap);
296- }
297-
298- if (!tabIdTreeIdVmMap.ContainsKey(treeId))
299- {
300- tabIdTreeIdVmMap.Add(treeId, treeVm);
301-
302- logger.Trace("AddTabIdTreeIdViewModelMap: tab {0} -> tree {1} -> VM[{2}] added.",
303- tabId, treeId, treeVm.ToHashString());
304- }
305- }
306-
307- public IEnumerable<IFolderTreeViewModel> FindTreeViewModelsByTabId(string tabId)
308- {
309- if (!this.tabIdVmMap.TryGetValue(
310- tabId, out IDictionary<string, IFolderTreeViewModel> tabIdTreeIdVmMap))
311- {
312- throw new ArgumentException("invalid tab id");
313- }
314-
315- return tabIdTreeIdVmMap.Select(x => x.Value);
316- }
317-
318269 public void RefreshFolderTree(string treeId, FolderTree tree)
319270 {
320- IFolderTreeViewModel treeVm = FindTreeIdViewModelMapByTreeId(treeId);
271+ IFolderTreeViewModel treeVm = this.InterVmStore.FindTreeIdViewModelMapByTreeId(treeId);
321272
322273 treeVm.Refresh(tree);
323274 treeVm.Nodes.First().IsSelected.Value = true;
324275 }
325276
326- private IFolderTreeViewModel FindTreeIdViewModelMapByTreeId(string treeId)
327- {
328- if (!this.treeIdVmMap.TryGetValue(treeId, out IFolderTreeViewModel vm))
329- {
330- throw new ArgumentException("invalid tree id");
331- }
332- return vm;
333- }
334-
335- public IEnumerable<IFolderTreeViewModel> GetTreeViewModels()
336- {
337- return this.treeIdVmMap.Values;
338- }
339-
340277 public void NotifyExpandedFolderChanged(
341278 string sourceRegionName, string relativePath,
342279 RecursiveSearchLevel level, bool isExpanded)