@@ -27,9 +27,11 @@ public partial class FileExplorerTreeView : UserControl
2727 public event EventHandler TreeNodeRenamed ;
2828
2929 private bool isEditMode = false ;
30- private string previousFileName ;
30+ private string renamingNodeId ;
31+ private string renamingNodeFileName ;
3132 private TextBlock lblRename ;
3233 private TextBox txtRename ;
34+
3335 private TreeNode currentTreeNode ;
3436 private TreeViewItem currentTreeViewItem ;
3537
@@ -87,6 +89,12 @@ private void TreeViewMain_PreviewMouseLeftButtonDown(object sender, MouseButtonE
8789
8890 currentTreeNode = currentTreeViewItem != null ?
8991 currentTreeViewItem . DataContext as TreeNode : null ;
92+
93+ // In case changing focus to a different node while renaming file
94+ if ( currentTreeNode != null && isEditMode && currentTreeNode . Id != renamingNodeId )
95+ {
96+ txtRename_LostFocus ( sender , null ) ;
97+ }
9098 }
9199
92100 private void TreeViewMain_PreviewMouseRightButtonDown ( object sender , MouseButtonEventArgs e )
@@ -176,7 +184,9 @@ private void mnuRename_Click(object sender, RoutedEventArgs e)
176184 txtRename . Focus ( ) ;
177185
178186 isEditMode = true ;
179- previousFileName = txtRename . Text ;
187+
188+ renamingNodeId = currentTreeNode . Id ;
189+ renamingNodeFileName = currentTreeNode . FileName ;
180190 }
181191
182192 private void mnuDelete_Click ( object sender , RoutedEventArgs e )
@@ -309,7 +319,7 @@ private void txtRename_KeyDown(object sender, KeyEventArgs e)
309319 txtRename_LostFocus ( sender , null ) ;
310320 else if ( e . Key == Key . Escape )
311321 {
312- txtRename . Text = previousFileName ;
322+ txtRename . Text = lblRename . Text = renamingNodeFileName ;
313323 txtRename_LostFocus ( sender , null ) ;
314324 }
315325 }
@@ -324,41 +334,56 @@ private void txtRename_LostFocus(object sender, RoutedEventArgs e)
324334 {
325335 txtRename . Text = txtRename . Text . Trim ( ) ;
326336
327- if ( isEditMode && currentTreeViewItem != null && previousFileName != txtRename . Text )
337+ if ( isEditMode )
328338 {
329- var basePath = Path . GetDirectoryName ( currentTreeNode . FileFullPath ) ;
330- var previousPath = Path . Combine ( basePath , previousFileName ) ;
331- var newPath = Path . Combine ( basePath , txtRename . Text ) ;
332-
333- if ( currentTreeNode . Type == TreeNodeType . File && File . Exists ( previousPath ) )
339+ if ( string . IsNullOrWhiteSpace ( txtRename . Text ) )
334340 {
335- File . Move ( previousPath , newPath ) ;
336-
337- hasRenamed = true ;
341+ MessageBox . Show ( "Please enter a file name." ) ;
342+ txtRename . Text = lblRename . Text = renamingNodeFileName ;
343+ return ;
338344 }
339- else if ( currentTreeNode . Type == TreeNodeType . Folder && Directory . Exists ( previousPath ) )
345+
346+ if ( currentTreeViewItem != null && renamingNodeFileName != txtRename . Text )
340347 {
341- // Necessary to move to another temporary path before moving to the new path, as directory renaming is not case-sensitive
342- // i.e. Renaming a folder from "Service" to "ServicE" would throw an exception using Directory.Move
343- var directory = new DirectoryInfo ( previousPath ) ;
344- directory . MoveTo ( PathHelper . GetDirectoryTemporaryPath ( previousPath ) ) ;
345- directory . MoveTo ( newPath ) ;
348+ var renamingTreeNode = DataSourceDictionary [ renamingNodeId ] ;
346349
347- hasRenamed = true ;
348- }
350+ var basePath = Path . GetDirectoryName ( renamingTreeNode . FileFullPath ) ;
351+ var previousPath = Path . Combine ( basePath , renamingNodeFileName ) ;
352+ var newPath = Path . Combine ( basePath , txtRename . Text ) ;
349353
350- if ( hasRenamed )
351- {
352- currentTreeNode . FileName = txtRename . Text ;
353- currentTreeNode . FileFullPath = newPath ;
354+ if ( renamingTreeNode . Type == TreeNodeType . File && File . Exists ( previousPath ) )
355+ {
356+ File . Move ( previousPath , newPath ) ;
354357
355- currentTreeNode . Parent . Children = currentTreeNode . Parent . Children . OrderBy ( p => p . Type ) . ThenBy ( p => p . FileName ) . ToList ( ) ;
358+ hasRenamed = true ;
359+ }
360+ else if ( renamingTreeNode . Type == TreeNodeType . Folder && Directory . Exists ( previousPath ) )
361+ {
362+ // Necessary to move to another temporary path before moving to the new path, as directory renaming is not case-sensitive
363+ // i.e. Renaming a folder from "Service" to "ServicE" would throw an exception using Directory.Move
364+ var directory = new DirectoryInfo ( previousPath ) ;
365+ directory . MoveTo ( PathHelper . GetDirectoryTemporaryPath ( previousPath ) ) ;
366+ directory . MoveTo ( newPath ) ;
356367
357- currentTreeViewItem . IsSelected = true ;
368+ hasRenamed = true ;
369+ }
358370
359- if ( TreeNodeRenamed != null )
371+ if ( hasRenamed )
360372 {
361- TreeNodeRenamed ( currentTreeNode , EventArgs . Empty ) ;
373+ renamingTreeNode . FileName = lblRename . Text = txtRename . Text ;
374+ renamingTreeNode . FileFullPath = newPath ;
375+
376+ renamingTreeNode . Parent . Children = renamingTreeNode . Parent . Children . OrderBy ( p => p . Type ) . ThenBy ( p => p . FileName ) . ToList ( ) ;
377+
378+ if ( renamingNodeId == currentTreeNode . Id )
379+ {
380+ currentTreeViewItem . IsSelected = true ;
381+ }
382+
383+ if ( TreeNodeRenamed != null )
384+ {
385+ TreeNodeRenamed ( renamingTreeNode , EventArgs . Empty ) ;
386+ }
362387 }
363388 }
364389 }
@@ -369,6 +394,10 @@ private void txtRename_LostFocus(object sender, RoutedEventArgs e)
369394 {
370395 RefreshTreeView ( ) ;
371396 }
397+ else
398+ {
399+ txtRename . Text = lblRename . Text = renamingNodeFileName ;
400+ }
372401
373402 lblRename . Visibility = Visibility . Visible ;
374403 txtRename . Visibility = Visibility . Collapsed ;
0 commit comments