-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathExplorer.vb
More file actions
250 lines (199 loc) · 8.43 KB
/
Explorer.vb
File metadata and controls
250 lines (199 loc) · 8.43 KB
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
Public MustInherit Class Explorer
Inherits Control
Public Sub New()
Dim resourceLocater As Uri = New Uri("/DiagramHelper;component/Resources/explorerdecorator.xaml", System.UriKind.Relative)
Dim ResDec As ResourceDictionary = Application.LoadComponent(resourceLocater)
Me.Resources.MergedDictionaries.Add(ResDec)
Me.Style = FindResource("ExplorerStyle")
End Sub
Public WithEvents FilesList As ListBox
Protected MustOverride ReadOnly Property ItemsSource As Specialized.INotifyCollectionChanged
Protected MustOverride Sub OnDeleteItem()
Protected MustOverride Function OnBeginEdit() As Boolean
Protected MustOverride Function OnCommit(newName As String) As Boolean
Protected MustOverride Sub OnSelectionChanged()
Dim firstTime As Boolean = True
Public Event ItemDoubleClick(sender As Object, e As MouseButtonEventArgs)
Private Sub Explorer_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
If firstTime Then
firstTime = False
FilesList = TryCast(Template.FindName("PART_ListBox", Me), ListBox)
FilesList.ItemContainerStyle = FindResource("listBoxItemStyle")
FilesList.ItemsSource = ItemsSource
AddHandler ItemsSource.CollectionChanged,
Sub()
Helper.Dispatcher.BeginInvoke(
Windows.Threading.DispatcherPriority.Background,
Sub() FilesList.ScrollIntoView(FilesList.SelectedItem)
)
End Sub
If FilesList.Items.Count > 0 Then FilesList.SelectedIndex = 0
End If
FilesList.ScrollIntoView(FilesList.SelectedItem)
End Sub
Public FreezListFiles As Boolean
Dim selectedAt As Date
Public Property SelectedIndex As Integer
Get
Return FilesList.SelectedIndex
End Get
Set(value As Integer)
If FilesList IsNot Nothing AndAlso value < FilesList.Items.Count Then
FreezListFiles = True
FilesList.SelectedIndex = value
FreezListFiles = False
End If
End Set
End Property
Private Sub FilesList_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles FilesList.SelectionChanged
item = FilesList.ItemContainerGenerator.ContainerFromItem(FilesList.SelectedItem)
If FreezListFiles Then Return
Dim i = FilesList.SelectedIndex
If i = -1 Then Return
selectedAt = Now
OnSelectionChanged()
FilesList.ScrollIntoView(FilesList.SelectedItem)
End Sub
Private Sub FilesList_KeyDown(sender As Object, e As KeyEventArgs) Handles FilesList.KeyDown
Select Case e.Key
Case Key.F2
BeginEdit()
e.Handled = True
Case Key.Enter
RaiseEvent ItemDoubleClick(Me, Nothing)
e.Handled = True
Case Key.Delete
OnDeleteItem()
End Select
End Sub
#Region "Edit Item Name"
Dim item As ListBoxItem
Dim txtBlock As TextBlock
Dim editorGrid As Grid
Dim editTextBox As TextBox
Dim inEditMode As Boolean = False
Dim ClickCount As Integer
Private Sub FilesList_PreviewMouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles FilesList.PreviewMouseLeftButtonDown
item = Helper.GetListBoxItem(e.OriginalSource)
If item Is Nothing Then
If inEditMode Then Commit()
ElseIf e.ClickCount = 2 Then
ClickCount = 2
item.IsSelected = True
e.Handled = True
If Helper.GetParent(Of TextBox)(e.OriginalSource) IsNot Nothing Then Return
RaiseEvent ItemDoubleClick(sender, e)
ElseIf (Now - selectedAt).TotalMilliseconds > 200 AndAlso
TypeOf e.OriginalSource Is TextBlock AndAlso
item.IsSelected AndAlso item.IsFocused Then
ClickCount = 1
item.IsSelected = True
e.Handled = True
Helper.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Background,
Sub()
If ClickCount = 2 Then Return
BeginEdit()
selectedAt = Now
End Sub)
End If
End Sub
Public Sub BeginEdit()
If Not OnBeginEdit() Then Return
inEditMode = True
Dim brdr As Border = VisualTreeHelper.GetChild(item, 0)
Dim grid As Grid = brdr.Child
txtBlock = grid.Children(0)
editorGrid = grid.Children(1)
editTextBox = editorGrid.Children(1)
txtBlock.Visibility = Visibility.Collapsed
' don't use textBlock because it is bound to data context
Dim s = item.Content.ToString().Substring(3).Trim(" ", "*")
If s.EndsWith(".xaml") Then s = s.Substring(0, s.Length - 5)
editTextBox.Text = s
editorGrid.Visibility = Visibility.Visible
editTextBox.Focus()
editTextBox.SelectAll()
AddHandler editTextBox.PreviewKeyDown, AddressOf editTextBox_PreviewKeyDown
AddHandler editTextBox.PreviewTextInput, AddressOf editTextBox_PreviewTextInput
AddHandler editTextBox.PreviewLostKeyboardFocus, AddressOf editTextBox_LostFocus
End Sub
Public Sub CancelEdit()
RemoveHandler editTextBox.PreviewKeyDown, AddressOf editTextBox_PreviewKeyDown
RemoveHandler editTextBox.PreviewTextInput, AddressOf editTextBox_PreviewTextInput
RemoveHandler editTextBox.PreviewLostKeyboardFocus, AddressOf editTextBox_LostFocus
editorGrid.Visibility = Visibility.Collapsed
txtBlock.Visibility = Visibility.Visible
inEditMode = False
End Sub
Dim committing As Boolean
Public Function Commit() As Boolean
If committing Then Return False
Dim newName = editTextBox.Text
committing = True
If OnCommit(newName) Then
editorGrid.Visibility = Visibility.Collapsed
txtBlock.Visibility = Visibility.Visible
selectedAt = Now
inEditMode = False
committing = False
Return True
End If
committing = False
Return False
End Function
Private Sub editTextBox_PreviewKeyDown(sender As Object, e As KeyEventArgs)
Select Case e.Key
Case Key.Space
Beep()
e.Handled = True
Case Key.Escape
CancelEdit()
e.Handled = True
item?.Focus()
Case Key.Enter
If Commit() Then
RemoveHandler editTextBox.PreviewKeyDown, AddressOf editTextBox_PreviewKeyDown
RemoveHandler editTextBox.PreviewTextInput, AddressOf editTextBox_PreviewTextInput
RemoveHandler editTextBox.PreviewLostKeyboardFocus, AddressOf editTextBox_LostFocus
item?.Focus()
End If
e.Handled = True
End Select
End Sub
Public Sub editTextBox_PreviewTextInput(sender As Object, e As TextCompositionEventArgs)
Select Case e.Text.ToLower
Case "a" To "z", "_", "0" To "9"
' allowed
Case Else
Beep()
e.Handled = True
End Select
End Sub
Public Sub editTextBox_LostFocus(sender As Object, e As KeyboardFocusChangedEventArgs)
If Commit() Then
RemoveHandler editTextBox.PreviewKeyDown, AddressOf editTextBox_PreviewKeyDown
RemoveHandler editTextBox.PreviewTextInput, AddressOf editTextBox_PreviewTextInput
RemoveHandler editTextBox.PreviewLostKeyboardFocus, AddressOf editTextBox_LostFocus
Else
e.Handled = True
Helper.Dispatcher.BeginInvoke(
Windows.Threading.DispatcherPriority.Background,
Sub() editTextBox.Focus()
)
End If
End Sub
Public Property Title As String
Get
Return GetValue(TitleProperty)
End Get
Set(value As String)
SetValue(TitleProperty, value)
End Set
End Property
Public Shared ReadOnly TitleProperty As DependencyProperty =
DependencyProperty.Register("Title",
GetType(String), GetType(Explorer),
New PropertyMetadata(Nothing))
#End Region
End Class