diff --git a/src/Files.Uwp/BaseLayout.cs b/src/Files.Uwp/BaseLayout.cs index 270d9d813d43..bc06dc96d5f9 100644 --- a/src/Files.Uwp/BaseLayout.cs +++ b/src/Files.Uwp/BaseLayout.cs @@ -83,8 +83,6 @@ public abstract class BaseLayout : Page, IBaseLayout, INotifyPropertyChanged public string OldItemName { get; set; } = null; - public TextBlock RenamingTextBlock { get; set; } = null; - private bool isMiddleClickToScrollEnabled = true; public bool IsMiddleClickToScrollEnabled @@ -1236,6 +1234,26 @@ public void ResetRenameDoubleClick() preRenamingItem = null; tapDebounceTimer.Stop(); } + + protected async void ValidateItemNameInputText(TextBox textBox, TextBoxBeforeTextChangingEventArgs args, Action showError) + { + if (FilesystemHelpers.ContainsRestrictedCharacters(args.NewText)) + { + args.Cancel = true; + await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + var oldSelection = textBox.SelectionStart + textBox.SelectionLength; + var oldText = textBox.Text; + textBox.Text = FilesystemHelpers.FilterRestrictedCharacters(args.NewText); + textBox.SelectionStart = oldSelection + textBox.Text.Length - oldText.Length; + showError?.Invoke(true); + }); + } + else + { + showError?.Invoke(false); + } + } } public class ContextMenuExtensions : DependencyObject diff --git a/src/Files.Uwp/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs b/src/Files.Uwp/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs index 8b80cc10305f..6a0d88414cdc 100644 --- a/src/Files.Uwp/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs +++ b/src/Files.Uwp/Filesystem/FilesystemOperations/Helpers/FilesystemHelpers.cs @@ -810,6 +810,16 @@ public static async Task> GetDraggedStorageIte return itemsList; } + public static string FilterRestrictedCharacters(string input) + { + int invalidCharIndex; + while ((invalidCharIndex = input.IndexOfAny(RestrictedCharacters)) >= 0) + { + input = input.Remove(invalidCharIndex, 1); + } + return input; + } + public static bool ContainsRestrictedCharacters(string input) { return input.IndexOfAny(RestrictedCharacters) >= 0; diff --git a/src/Files.Uwp/Helpers/DynamicDialogFactory.cs b/src/Files.Uwp/Helpers/DynamicDialogFactory.cs index c8b42fd723ad..43fdd5f40cd2 100644 --- a/src/Files.Uwp/Helpers/DynamicDialogFactory.cs +++ b/src/Files.Uwp/Helpers/DynamicDialogFactory.cs @@ -56,27 +56,35 @@ public static DynamicDialog GetFor_RenameDialog() Opacity = 0.0d }; - inputText.TextChanged += (s, e) => + inputText.BeforeTextChanging += async (textBox, args) => { - var textBox = s as TextBox; - dialog.ViewModel.AdditionalData = textBox.Text; - - if (FilesystemHelpers.ContainsRestrictedCharacters(textBox.Text)) - { - dialog.ViewModel.DynamicButtonsEnabled = DynamicDialogButtons.Cancel; - tipText.Opacity = 1.0d; - return; - } - else if (!string.IsNullOrWhiteSpace(textBox.Text)) + if (FilesystemHelpers.ContainsRestrictedCharacters(args.NewText)) { - dialog.ViewModel.DynamicButtonsEnabled = DynamicDialogButtons.Primary | DynamicDialogButtons.Cancel; + args.Cancel = true; + await inputText.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => + { + var oldSelection = textBox.SelectionStart + textBox.SelectionLength; + var oldText = textBox.Text; + textBox.Text = FilesystemHelpers.FilterRestrictedCharacters(args.NewText); + textBox.SelectionStart = oldSelection + textBox.Text.Length - oldText.Length; + tipText.Opacity = 1.0d; + }); } else { - dialog.ViewModel.DynamicButtonsEnabled = DynamicDialogButtons.Cancel; - } + dialog.ViewModel.AdditionalData = textBox.Text; - tipText.Opacity = 0.0d; + if (!string.IsNullOrWhiteSpace(textBox.Text)) + { + dialog.ViewModel.DynamicButtonsEnabled = DynamicDialogButtons.Primary | DynamicDialogButtons.Cancel; + } + else + { + dialog.ViewModel.DynamicButtonsEnabled = DynamicDialogButtons.Cancel; + } + + tipText.Opacity = 0.0d; + } }; inputText.Loaded += (s, e) => diff --git a/src/Files.Uwp/Views/LayoutModes/ColumnViewBase.xaml b/src/Files.Uwp/Views/LayoutModes/ColumnViewBase.xaml index d10417d9c8ef..d256c5785a51 100644 --- a/src/Files.Uwp/Views/LayoutModes/ColumnViewBase.xaml +++ b/src/Files.Uwp/Views/LayoutModes/ColumnViewBase.xaml @@ -310,8 +310,8 @@ Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" + BeforeTextChanging="ItemNameTextBox_BeforeTextChanging" TextAlignment="Left" - TextChanged="ListViewTextBoxItemName_TextChanged" TextWrapping="Wrap" Visibility="Collapsed" /> diff --git a/src/Files.Uwp/Views/LayoutModes/ColumnViewBase.xaml.cs b/src/Files.Uwp/Views/LayoutModes/ColumnViewBase.xaml.cs index 775c47ff76e9..d677f40ac684 100644 --- a/src/Files.Uwp/Views/LayoutModes/ColumnViewBase.xaml.cs +++ b/src/Files.Uwp/Views/LayoutModes/ColumnViewBase.xaml.cs @@ -126,25 +126,6 @@ protected override void UnhookEvents() } } - private void ListViewTextBoxItemName_TextChanged(object sender, TextChangedEventArgs e) - { - var textBox = sender as TextBox; - - if (FilesystemHelpers.ContainsRestrictedCharacters(textBox.Text)) - { - FileNameTeachingTip.Visibility = Visibility.Visible; - FileNameTeachingTip.IsOpen = true; - } - else - { - if (FileNameTeachingTip.IsOpen == true) - { - FileNameTeachingTip.IsOpen = false; - FileNameTeachingTip.Visibility = Visibility.Collapsed; - } - } - } - public event EventHandler ItemInvoked; protected override void OnNavigatedTo(NavigationEventArgs eventArgs) @@ -199,13 +180,11 @@ override public void StartRenameItem() { return; } - RenamingTextBlock = listViewItem.FindDescendant("ItemName") as TextBlock; + TextBlock textBlock = listViewItem.FindDescendant("ItemName") as TextBlock; textBox = listViewItem.FindDescendant("ListViewTextBoxItemName") as TextBox; - //textBlock = (listViewItem.ContentTemplateRoot as Border).FindDescendant("ItemName") as TextBlock; - //textBox = (listViewItem.ContentTemplateRoot as Border).FindDescendant("ListViewTextBoxItemName") as TextBox; - textBox.Text = RenamingTextBlock.Text; - OldItemName = RenamingTextBlock.Text; - RenamingTextBlock.Visibility = Visibility.Collapsed; + textBox.Text = textBlock.Text; + OldItemName = textBlock.Text; + textBlock.Visibility = Visibility.Collapsed; textBox.Visibility = Visibility.Visible; textBox.Focus(FocusState.Pointer); @@ -221,6 +200,15 @@ override public void StartRenameItem() IsRenamingItem = true; } + private void ItemNameTextBox_BeforeTextChanging(TextBox textBox, TextBoxBeforeTextChangingEventArgs args) + { + ValidateItemNameInputText(textBox, args, (showError) => + { + FileNameTeachingTip.Visibility = showError ? Visibility.Visible : Visibility.Collapsed; + FileNameTeachingTip.IsOpen = showError; + }); + } + private void RenameTextBox_KeyDown(object sender, KeyRoutedEventArgs e) { if (e.Key == VirtualKey.Escape) @@ -269,8 +257,9 @@ private void EndRename(TextBox textBox) ListViewItem listViewItem = FileList.ContainerFromItem(RenamingItem) as ListViewItem; listViewItem?.Focus(FocusState.Programmatic); + TextBlock textBlock = listViewItem.FindDescendant("ItemName") as TextBlock; textBox.Visibility = Visibility.Collapsed; - RenamingTextBlock.Visibility = Visibility.Visible; + textBlock.Visibility = Visibility.Visible; } textBox.LostFocus -= RenameTextBox_LostFocus; diff --git a/src/Files.Uwp/Views/LayoutModes/DetailsLayoutBrowser.xaml b/src/Files.Uwp/Views/LayoutModes/DetailsLayoutBrowser.xaml index 8a50e8853e48..4c17ca82dc9b 100644 --- a/src/Files.Uwp/Views/LayoutModes/DetailsLayoutBrowser.xaml +++ b/src/Files.Uwp/Views/LayoutModes/DetailsLayoutBrowser.xaml @@ -640,7 +640,7 @@ MaxWidth="{Binding MaxWidthForRenameTextbox, ElementName=PageRoot, Mode=OneWay}" HorizontalAlignment="Left" VerticalAlignment="Center" - TextChanged="ListViewTextBoxItemName_TextChanged" + BeforeTextChanging="ItemNameTextBox_BeforeTextChanging" Visibility="Collapsed"> diff --git a/src/Files.Uwp/Views/LayoutModes/DetailsLayoutBrowser.xaml.cs b/src/Files.Uwp/Views/LayoutModes/DetailsLayoutBrowser.xaml.cs index 5ee9f09f37a2..b62842b9682a 100644 --- a/src/Files.Uwp/Views/LayoutModes/DetailsLayoutBrowser.xaml.cs +++ b/src/Files.Uwp/Views/LayoutModes/DetailsLayoutBrowser.xaml.cs @@ -345,8 +345,6 @@ override public void StartRenameItem() } TextBlock textBlock = listViewItem.FindDescendant("ItemName") as TextBlock; textBox = listViewItem.FindDescendant("ItemNameTextBox") as TextBox; - //TextBlock textBlock = (gridViewItem.ContentTemplateRoot as Grid).FindName("ItemName") as TextBlock; - //textBox = (gridViewItem.ContentTemplateRoot as Grid).FindName("TileViewTextBoxItemName") as TextBox; textBox.Text = textBlock.Text; OldItemName = textBlock.Text; textBlock.Visibility = Visibility.Collapsed; @@ -366,20 +364,13 @@ override public void StartRenameItem() IsRenamingItem = true; } - private void ListViewTextBoxItemName_TextChanged(object sender, TextChangedEventArgs e) + private void ItemNameTextBox_BeforeTextChanging(TextBox textBox, TextBoxBeforeTextChangingEventArgs args) { - var textBox = sender as TextBox; - - if (FilesystemHelpers.ContainsRestrictedCharacters(textBox.Text)) - { - FileNameTeachingTip.Visibility = Visibility.Visible; - FileNameTeachingTip.IsOpen = true; - } - else + ValidateItemNameInputText(textBox, args, (showError) => { - FileNameTeachingTip.IsOpen = false; - FileNameTeachingTip.Visibility = Visibility.Collapsed; - } + FileNameTeachingTip.Visibility = showError ? Visibility.Visible : Visibility.Collapsed; + FileNameTeachingTip.IsOpen = showError; + }); } private void RenameTextBox_KeyDown(object sender, KeyRoutedEventArgs e) diff --git a/src/Files.Uwp/Views/LayoutModes/GridViewBrowser.xaml b/src/Files.Uwp/Views/LayoutModes/GridViewBrowser.xaml index 244450ad8490..a58eeb55b3db 100644 --- a/src/Files.Uwp/Views/LayoutModes/GridViewBrowser.xaml +++ b/src/Files.Uwp/Views/LayoutModes/GridViewBrowser.xaml @@ -197,9 +197,9 @@ HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource SolidBackgroundFillColorSecondary}" + BeforeTextChanging="ItemNameTextBox_BeforeTextChanging" Text="{x:Bind ItemName, Mode=OneWay}" TextAlignment="Center" - TextChanged="GridViewTextBoxItemName_TextChanged" TextWrapping="Wrap" /> @@ -337,8 +337,8 @@ x:Name="TileViewTextBoxItemName" Grid.Row="0" HorizontalAlignment="Left" + BeforeTextChanging="ItemNameTextBox_BeforeTextChanging" Text="{x:Bind ItemName, Mode=OneWay}" - TextChanged="GridViewTextBoxItemName_TextChanged" Visibility="Collapsed" /> { - FileNameTeachingTip.Visibility = Visibility.Visible; - FileNameTeachingTip.IsOpen = true; - } - else - { - FileNameTeachingTip.IsOpen = false; - FileNameTeachingTip.Visibility = Visibility.Collapsed; - } + FileNameTeachingTip.Visibility = showError ? Visibility.Visible : Visibility.Collapsed; + FileNameTeachingTip.IsOpen = showError; + }); } private void RenameTextBox_KeyDown(object sender, KeyRoutedEventArgs e)