@@ -17,7 +17,9 @@ public interface ITreeNode
1717 string Path { get ; set ; }
1818 string Label { get ; set ; }
1919 int Level { get ; set ; }
20+ bool IsContainer { get ; set ; }
2021 bool IsFolder { get ; set ; }
22+ bool IsFolderOrContainer { get ; }
2123 bool IsCollapsed { get ; set ; }
2224 bool IsHidden { get ; set ; }
2325 bool IsActive { get ; set ; }
@@ -52,29 +54,45 @@ public void Load(IEnumerable<TData> treeDatas)
5254 var isCheckable = IsCheckable ;
5355
5456 var isSelected = IsSelectable && selectedNodePath != null && Title == selectedNodePath ;
55- AddNode ( Title , Title , - 1 + displayRootLevel , true , false , false , false , isSelected , false , null ) ;
57+ AddNode ( Title , Title , - 1 + displayRootLevel , true , false , false , false , isSelected , false , null , false ) ;
5658
5759 var hideChildren = false ;
5860 var hideChildrenBelowLevel = 0 ;
5961
6062 var folders = new HashSet < string > ( ) ;
6163
64+ TNode lastAddedNode = null ;
6265 foreach ( var treeData in treeDatas )
6366 {
6467 var parts = treeData . Path . Split ( new [ ] { pathSeparator } , StringSplitOptions . None ) ;
65- for ( var i = 0 ; i < parts . Length ; i ++ )
68+ for ( var level = 0 ; level < parts . Length ; level ++ )
6669 {
67- var label = parts [ i ] ;
68- var level = i + 1 ;
69- var nodePath = String . Join ( pathSeparator , parts , 0 , level ) ;
70- var isFolder = i < parts . Length - 1 ;
70+ var label = parts [ level ] ;
71+ var nodePath = String . Join ( pathSeparator , parts , 0 , level + 1 ) ;
72+ var isFolder = level < parts . Length - 1 ;
73+ var parentIsPromoted = false ;
74+
75+ if ( lastAddedNode != null )
76+ {
77+ if ( ! lastAddedNode . IsFolder )
78+ {
79+ if ( PromoteNode ( lastAddedNode , label ) )
80+ {
81+ Logger . Trace ( "Promoting Node Label:{0}" , lastAddedNode . Label ) ;
82+
83+ parentIsPromoted = true ;
84+ lastAddedNode . IsContainer = true ;
85+ }
86+ }
87+ }
88+
7189 var alreadyExists = folders . Contains ( nodePath ) ;
7290 if ( ! alreadyExists )
7391 {
7492 var nodeIsHidden = false ;
7593 if ( hideChildren )
7694 {
77- if ( level <= hideChildrenBelowLevel )
95+ if ( level + 1 <= hideChildrenBelowLevel )
7896 {
7997 hideChildren = false ;
8098 }
@@ -100,7 +118,7 @@ public void Load(IEnumerable<TData> treeDatas)
100118 if ( ! hideChildren )
101119 {
102120 hideChildren = true ;
103- hideChildrenBelowLevel = level ;
121+ hideChildrenBelowLevel = level + 1 ;
104122 }
105123 }
106124 }
@@ -112,8 +130,9 @@ public void Load(IEnumerable<TData> treeDatas)
112130 }
113131
114132 isSelected = selectedNodePath != null && nodePath == selectedNodePath ;
115- AddNode ( nodePath , label , i + displayRootLevel , isFolder , isActive , nodeIsHidden ,
116- nodeIsCollapsed , isSelected , isChecked , treeNodeTreeData ) ;
133+
134+ lastAddedNode = AddNode ( nodePath , label , level + displayRootLevel + ( parentIsPromoted ? 1 : 0 ) , isFolder , isActive , nodeIsHidden ,
135+ nodeIsCollapsed , isSelected , isChecked , treeNodeTreeData , false ) ;
117136 }
118137 }
119138 }
@@ -124,7 +143,7 @@ public void Load(IEnumerable<TData> treeDatas)
124143 for ( var index = nodes . Count - 1 ; index >= 0 ; index -- )
125144 {
126145 var node = nodes [ index ] ;
127- if ( node . Level >= 0 && node . IsFolder )
146+ if ( node . Level >= 0 && node . IsFolderOrContainer )
128147 {
129148 bool ? anyChecked = null ;
130149 bool ? allChecked = null ;
@@ -150,6 +169,27 @@ public void Load(IEnumerable<TData> treeDatas)
150169 }
151170 }
152171
172+ protected bool PromoteNode ( TNode previouslyAddedNode , string nextLabel )
173+ {
174+ if ( ! PromoteMetaFiles )
175+ {
176+ return false ;
177+ }
178+
179+ if ( previouslyAddedNode == null )
180+ {
181+ return false ;
182+ }
183+
184+ if ( ! nextLabel . EndsWith ( ".meta" ) )
185+ {
186+ return false ;
187+ }
188+
189+ var substring = nextLabel . Substring ( 0 , nextLabel . Length - 5 ) ;
190+ return previouslyAddedNode . Label == substring ;
191+ }
192+
153193 public void SetCheckStateOnAll ( bool isChecked )
154194 {
155195 var nodeCheckState = isChecked ? CheckState . Checked : CheckState . Empty ;
@@ -174,9 +214,9 @@ public void SetCheckStateOnAll(bool isChecked)
174214
175215 protected abstract IEnumerable < string > GetCollapsedFolders ( ) ;
176216
177- protected void AddNode ( string path , string label , int level , bool isFolder , bool isActive , bool isHidden , bool isCollapsed , bool isSelected , bool isChecked , TData ? treeData )
217+ protected TNode AddNode ( string path , string label , int level , bool isFolder , bool isActive , bool isHidden , bool isCollapsed , bool isSelected , bool isChecked , TData ? treeData , bool isContainer )
178218 {
179- var node = CreateTreeNode ( path , label , level , isFolder , isActive , isHidden , isCollapsed , isChecked , treeData ) ;
219+ var node = CreateTreeNode ( path , label , level , isFolder , isActive , isHidden , isCollapsed , isChecked , treeData , isContainer ) ;
180220
181221 SetNodeIcon ( node ) ;
182222 Nodes . Add ( node ) ;
@@ -185,6 +225,8 @@ protected void AddNode(string path, string label, int level, bool isFolder, bool
185225 {
186226 SelectedNode = node ;
187227 }
228+
229+ return node ;
188230 }
189231
190232 protected void Clear ( )
@@ -198,7 +240,7 @@ protected void Clear()
198240
199241 protected abstract void AddCheckedNode ( TNode node ) ;
200242
201- protected abstract TNode CreateTreeNode ( string path , string label , int level , bool isFolder , bool isActive , bool isHidden , bool isCollapsed , bool isChecked , TData ? treeData ) ;
243+ protected abstract TNode CreateTreeNode ( string path , string label , int level , bool isFolder , bool isActive , bool isHidden , bool isCollapsed , bool isChecked , TData ? treeData , bool isContainer ) ;
202244
203245 protected abstract void OnClear ( ) ;
204246
@@ -212,7 +254,7 @@ protected void ToggleNodeVisibility(int idx, TNode node)
212254 for ( ; idx < Nodes . Count && Nodes [ idx ] . Level > nodeLevel ; idx ++ )
213255 {
214256 Nodes [ idx ] . IsHidden = node . IsCollapsed ;
215- if ( Nodes [ idx ] . IsFolder && ! node . IsCollapsed && Nodes [ idx ] . IsCollapsed )
257+ if ( Nodes [ idx ] . IsFolderOrContainer && ! node . IsCollapsed && Nodes [ idx ] . IsCollapsed )
216258 {
217259 var level = Nodes [ idx ] . Level ;
218260 for ( idx ++ ; idx < Nodes . Count && Nodes [ idx ] . Level > level ; idx ++ )
@@ -245,11 +287,7 @@ protected void ToggleNodeChecked(int idx, TNode node)
245287 break ;
246288 }
247289
248- if ( node . IsFolder )
249- {
250- ToggleChildrenChecked ( idx , node , isChecked ) ;
251- }
252- else
290+ if ( ! node . IsFolder )
253291 {
254292 if ( isChecked )
255293 {
@@ -261,6 +299,11 @@ protected void ToggleNodeChecked(int idx, TNode node)
261299 }
262300 }
263301
302+ if ( node . IsFolderOrContainer )
303+ {
304+ ToggleChildrenChecked ( idx , node , isChecked ) ;
305+ }
306+
264307 ToggleParentFoldersChecked ( idx , node , isChecked ) ;
265308 }
266309
@@ -272,11 +315,7 @@ private void ToggleChildrenChecked(int idx, TNode node, bool isChecked)
272315 var wasChecked = childNode . CheckState == CheckState . Checked ;
273316 childNode . CheckState = isChecked ? CheckState . Checked : CheckState . Empty ;
274317
275- if ( childNode . IsFolder )
276- {
277- ToggleChildrenChecked ( i , childNode , isChecked ) ;
278- }
279- else
318+ if ( ! childNode . IsFolder )
280319 {
281320 if ( isChecked && ! wasChecked )
282321 {
@@ -287,6 +326,11 @@ private void ToggleChildrenChecked(int idx, TNode node, bool isChecked)
287326 RemoveCheckedNode ( childNode ) ;
288327 }
289328 }
329+
330+ if ( childNode . IsFolderOrContainer )
331+ {
332+ ToggleChildrenChecked ( i , childNode , isChecked ) ;
333+ }
290334 }
291335 }
292336
@@ -394,5 +438,6 @@ private void ToggleParentFoldersChecked(int idx, TNode node, bool isChecked)
394438 public abstract bool IsSelectable { get ; set ; }
395439 public abstract bool IsCheckable { get ; set ; }
396440 public abstract string PathSeparator { get ; set ; }
441+ protected abstract bool PromoteMetaFiles { get ; }
397442 }
398443}
0 commit comments