5
5
using System . Linq ;
6
6
using System . Reactive . Linq ;
7
7
using System . Runtime . InteropServices ;
8
- using Avalonia ;
9
8
using Avalonia . Controls ;
10
9
using Avalonia . Controls . Models . TreeDataGrid ;
11
10
using Avalonia . Controls . Selection ;
@@ -20,6 +19,9 @@ namespace TreeDataGridDemo.ViewModels
20
19
public class FilesPageViewModel : ReactiveObject
21
20
{
22
21
private static IconConverter ? s_iconConverter ;
22
+ private readonly HierarchicalTreeDataGridSource < FileTreeNodeModel > ? _treeSource ;
23
+ private FlatTreeDataGridSource < FileTreeNodeModel > ? _flatSource ;
24
+ private ITreeDataGridSource < FileTreeNodeModel > _source ;
23
25
private bool _cellSelection ;
24
26
private FileTreeNodeModel ? _root ;
25
27
private string _selectedDrive ;
@@ -38,61 +40,17 @@ public FilesPageViewModel()
38
40
_selectedDrive = Drives . FirstOrDefault ( ) ?? "/" ;
39
41
}
40
42
41
- Source = new HierarchicalTreeDataGridSource < FileTreeNodeModel > ( Array . Empty < FileTreeNodeModel > ( ) )
42
- {
43
- Columns =
44
- {
45
- new CheckBoxColumn < FileTreeNodeModel > (
46
- null ,
47
- x => x . IsChecked ,
48
- ( o , v ) => o . IsChecked = v ,
49
- options : new ( )
50
- {
51
- CanUserResizeColumn = false ,
52
- } ) ,
53
- new HierarchicalExpanderColumn < FileTreeNodeModel > (
54
- new TemplateColumn < FileTreeNodeModel > (
55
- "Name" ,
56
- "FileNameCell" ,
57
- "FileNameEditCell" ,
58
- new GridLength ( 1 , GridUnitType . Star ) ,
59
- new ( )
60
- {
61
- CompareAscending = FileTreeNodeModel . SortAscending ( x => x . Name ) ,
62
- CompareDescending = FileTreeNodeModel . SortDescending ( x => x . Name ) ,
63
- IsTextSearchEnabled = true ,
64
- TextSearchValueSelector = x => x . Name
65
- } ) ,
66
- x => x . Children ,
67
- x => x . HasChildren ,
68
- x => x . IsExpanded ) ,
69
- new TextColumn < FileTreeNodeModel , long ? > (
70
- "Size" ,
71
- x => x . Size ,
72
- options : new ( )
73
- {
74
- CompareAscending = FileTreeNodeModel . SortAscending ( x => x . Size ) ,
75
- CompareDescending = FileTreeNodeModel . SortDescending ( x => x . Size ) ,
76
- } ) ,
77
- new TextColumn < FileTreeNodeModel , DateTimeOffset ? > (
78
- "Modified" ,
79
- x => x . Modified ,
80
- options : new ( )
81
- {
82
- CompareAscending = FileTreeNodeModel . SortAscending ( x => x . Modified ) ,
83
- CompareDescending = FileTreeNodeModel . SortDescending ( x => x . Modified ) ,
84
- } ) ,
85
- }
86
- } ;
87
-
88
- Source . RowSelection ! . SingleSelect = false ;
89
- Source . RowSelection . SelectionChanged += SelectionChanged ;
43
+ _source = _treeSource = CreateTreeSource ( ) ;
90
44
91
45
this . WhenAnyValue ( x => x . SelectedDrive )
92
46
. Subscribe ( x =>
93
47
{
94
48
_root = new FileTreeNodeModel ( _selectedDrive , isDirectory : true , isRoot : true ) ;
95
- Source . Items = new [ ] { _root } ;
49
+
50
+ if ( _treeSource is not null )
51
+ _treeSource . Items = new [ ] { _root } ;
52
+ else if ( _flatSource is not null )
53
+ _flatSource . Items = _root . Children ;
96
54
} ) ;
97
55
}
98
56
@@ -115,6 +73,16 @@ public bool CellSelection
115
73
116
74
public IList < string > Drives { get ; }
117
75
76
+ public bool FlatList
77
+ {
78
+ get => Source != _treeSource ;
79
+ set
80
+ {
81
+ if ( value != FlatList )
82
+ Source = value ? _flatSource ??= CreateFlatSource ( ) : _treeSource ! ;
83
+ }
84
+ }
85
+
118
86
public string SelectedDrive
119
87
{
120
88
get => _selectedDrive ;
@@ -127,7 +95,11 @@ public string? SelectedPath
127
95
set => SetSelectedPath ( value ) ;
128
96
}
129
97
130
- public HierarchicalTreeDataGridSource < FileTreeNodeModel > Source { get ; }
98
+ public ITreeDataGridSource < FileTreeNodeModel > Source
99
+ {
100
+ get => _source ;
101
+ private set => this . RaiseAndSetIfChanged ( ref _source , value ) ;
102
+ }
131
103
132
104
public static IMultiValueConverter FileIconConverter
133
105
{
@@ -151,11 +123,115 @@ public static IMultiValueConverter FileIconConverter
151
123
}
152
124
}
153
125
126
+ private FlatTreeDataGridSource < FileTreeNodeModel > CreateFlatSource ( )
127
+ {
128
+ var result = new FlatTreeDataGridSource < FileTreeNodeModel > ( _root ! . Children )
129
+ {
130
+ Columns =
131
+ {
132
+ new CheckBoxColumn < FileTreeNodeModel > (
133
+ null ,
134
+ x => x . IsChecked ,
135
+ ( o , v ) => o . IsChecked = v ,
136
+ options : new ( )
137
+ {
138
+ CanUserResizeColumn = false ,
139
+ } ) ,
140
+ new TemplateColumn < FileTreeNodeModel > (
141
+ "Name" ,
142
+ "FileNameCell" ,
143
+ "FileNameEditCell" ,
144
+ new GridLength ( 1 , GridUnitType . Star ) ,
145
+ new ( )
146
+ {
147
+ CompareAscending = FileTreeNodeModel . SortAscending ( x => x . Name ) ,
148
+ CompareDescending = FileTreeNodeModel . SortDescending ( x => x . Name ) ,
149
+ IsTextSearchEnabled = true ,
150
+ TextSearchValueSelector = x => x . Name
151
+ } ) ,
152
+ new TextColumn < FileTreeNodeModel , long ? > (
153
+ "Size" ,
154
+ x => x . Size ,
155
+ options : new ( )
156
+ {
157
+ CompareAscending = FileTreeNodeModel . SortAscending ( x => x . Size ) ,
158
+ CompareDescending = FileTreeNodeModel . SortDescending ( x => x . Size ) ,
159
+ } ) ,
160
+ new TextColumn < FileTreeNodeModel , DateTimeOffset ? > (
161
+ "Modified" ,
162
+ x => x . Modified ,
163
+ options : new ( )
164
+ {
165
+ CompareAscending = FileTreeNodeModel . SortAscending ( x => x . Modified ) ,
166
+ CompareDescending = FileTreeNodeModel . SortDescending ( x => x . Modified ) ,
167
+ } ) ,
168
+ }
169
+ } ;
170
+
171
+ result . RowSelection ! . SingleSelect = false ;
172
+ result . RowSelection . SelectionChanged += SelectionChanged ;
173
+ return result ;
174
+ }
175
+
176
+ private HierarchicalTreeDataGridSource < FileTreeNodeModel > CreateTreeSource ( )
177
+ {
178
+ var result = new HierarchicalTreeDataGridSource < FileTreeNodeModel > ( Array . Empty < FileTreeNodeModel > ( ) )
179
+ {
180
+ Columns =
181
+ {
182
+ new CheckBoxColumn < FileTreeNodeModel > (
183
+ null ,
184
+ x => x . IsChecked ,
185
+ ( o , v ) => o . IsChecked = v ,
186
+ options : new ( )
187
+ {
188
+ CanUserResizeColumn = false ,
189
+ } ) ,
190
+ new HierarchicalExpanderColumn < FileTreeNodeModel > (
191
+ new TemplateColumn < FileTreeNodeModel > (
192
+ "Name" ,
193
+ "FileNameCell" ,
194
+ "FileNameEditCell" ,
195
+ new GridLength ( 1 , GridUnitType . Star ) ,
196
+ new ( )
197
+ {
198
+ CompareAscending = FileTreeNodeModel . SortAscending ( x => x . Name ) ,
199
+ CompareDescending = FileTreeNodeModel . SortDescending ( x => x . Name ) ,
200
+ IsTextSearchEnabled = true ,
201
+ TextSearchValueSelector = x => x . Name
202
+ } ) ,
203
+ x => x . Children ,
204
+ x => x . HasChildren ,
205
+ x => x . IsExpanded ) ,
206
+ new TextColumn < FileTreeNodeModel , long ? > (
207
+ "Size" ,
208
+ x => x . Size ,
209
+ options : new ( )
210
+ {
211
+ CompareAscending = FileTreeNodeModel . SortAscending ( x => x . Size ) ,
212
+ CompareDescending = FileTreeNodeModel . SortDescending ( x => x . Size ) ,
213
+ } ) ,
214
+ new TextColumn < FileTreeNodeModel , DateTimeOffset ? > (
215
+ "Modified" ,
216
+ x => x . Modified ,
217
+ options : new ( )
218
+ {
219
+ CompareAscending = FileTreeNodeModel . SortAscending ( x => x . Modified ) ,
220
+ CompareDescending = FileTreeNodeModel . SortDescending ( x => x . Modified ) ,
221
+ } ) ,
222
+ }
223
+ } ;
224
+
225
+ result . RowSelection ! . SingleSelect = false ;
226
+ result . RowSelection . SelectionChanged += SelectionChanged ;
227
+ return result ;
228
+ }
229
+
154
230
private void SetSelectedPath ( string ? value )
155
231
{
156
232
if ( string . IsNullOrEmpty ( value ) )
157
233
{
158
- Source . RowSelection ! . Clear ( ) ;
234
+ GetRowSelection ( Source ) . Clear ( ) ;
159
235
return ;
160
236
}
161
237
@@ -204,12 +280,18 @@ private void SetSelectedPath(string? value)
204
280
}
205
281
}
206
282
207
- Source . RowSelection ! . SelectedIndex = index ;
283
+ GetRowSelection ( Source ) . SelectedIndex = index ;
284
+ }
285
+
286
+ private ITreeDataGridRowSelectionModel < FileTreeNodeModel > GetRowSelection ( ITreeDataGridSource source )
287
+ {
288
+ return source . Selection as ITreeDataGridRowSelectionModel < FileTreeNodeModel > ??
289
+ throw new InvalidOperationException ( "Expected a row selection model." ) ;
208
290
}
209
291
210
292
private void SelectionChanged ( object ? sender , TreeSelectionModelSelectionChangedEventArgs < FileTreeNodeModel > e )
211
293
{
212
- var selectedPath = Source . RowSelection ? . SelectedItem ? . Path ;
294
+ var selectedPath = GetRowSelection ( Source ) . SelectedItem ? . Path ;
213
295
this . RaiseAndSetIfChanged ( ref _selectedPath , selectedPath , nameof ( SelectedPath ) ) ;
214
296
215
297
foreach ( var i in e . DeselectedItems )
0 commit comments