diff --git a/Microsoft.Toolkit.Uwp.DeveloperTools/FocusTracker/FocusTracker.cs b/Microsoft.Toolkit.Uwp.DeveloperTools/FocusTracker/FocusTracker.cs index 7aef4dc2fed..ee39f30ae9b 100644 --- a/Microsoft.Toolkit.Uwp.DeveloperTools/FocusTracker/FocusTracker.cs +++ b/Microsoft.Toolkit.Uwp.DeveloperTools/FocusTracker/FocusTracker.cs @@ -106,7 +106,16 @@ private void ClearContent() private void UpdateTimer_Tick(object sender, object e) { - var focusedControl = FocusManager.GetFocusedElement() as FrameworkElement; + FrameworkElement focusedControl; + + if (Windows.Foundation.Metadata.ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "XamlRoot") && XamlRoot != null) + { + focusedControl = FocusManager.GetFocusedElement(XamlRoot) as FrameworkElement; + } + else + { + focusedControl = FocusManager.GetFocusedElement() as FrameworkElement; + } if (focusedControl == null) { diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Shell.Search.cs b/Microsoft.Toolkit.Uwp.SampleApp/Shell.Search.cs index 45975cc7787..34730cc0a74 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Shell.Search.cs +++ b/Microsoft.Toolkit.Uwp.SampleApp/Shell.Search.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Linq; using Microsoft.Toolkit.Uwp.Helpers; using Microsoft.Toolkit.Uwp.UI.Extensions; @@ -16,7 +15,18 @@ public sealed partial class Shell { internal void StartSearch(string startingText = null) { - if (FocusManager.GetFocusedElement() == SearchBox.FindDescendant()) + object focusedElement; + + if (Windows.Foundation.Metadata.ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "XamlRoot") && XamlRoot != null) + { + focusedElement = FocusManager.GetFocusedElement(XamlRoot); + } + else + { + focusedElement = FocusManager.GetFocusedElement(); + } + + if (focusedElement == SearchBox.FindDescendant()) { return; } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/ApiInformationHelper.cs b/Microsoft.Toolkit.Uwp.UI.Animations/ApiInformationHelper.cs index b04fbca41f3..d2b26d7cd08 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/ApiInformationHelper.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/ApiInformationHelper.cs @@ -20,5 +20,7 @@ internal class ApiInformationHelper public static bool IsFallCreatorsUpdateOrAbove => (bool)(_isFallCreatorsUpdateOrAbove ?? (_isFallCreatorsUpdateOrAbove = ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 5))); + + public static bool IsXamlRootAvailable { get; } = ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "XamlRoot"); } } diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/QuickReturnHeaderBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/QuickReturnHeaderBehavior.cs index 69bff0cd858..3cb2a030d0c 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/QuickReturnHeaderBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/QuickReturnHeaderBehavior.cs @@ -258,7 +258,15 @@ private void ScrollViewer_GotFocus(object sender, RoutedEventArgs e) { var scroller = (ScrollViewer)sender; - var focusedElement = FocusManager.GetFocusedElement(); + object focusedElement; + if (ApiInformationHelper.IsXamlRootAvailable && scroller.XamlRoot != null) + { + focusedElement = FocusManager.GetFocusedElement(scroller.XamlRoot); + } + else + { + focusedElement = FocusManager.GetFocusedElement(); + } if (focusedElement is UIElement element) { diff --git a/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/StickyHeaderBehavior.cs b/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/StickyHeaderBehavior.cs index 3dfc01f4ea1..6eae922af7f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/StickyHeaderBehavior.cs +++ b/Microsoft.Toolkit.Uwp.UI.Animations/Behaviors/StickyHeaderBehavior.cs @@ -236,7 +236,15 @@ private void ScrollViewer_GotFocus(object sender, RoutedEventArgs e) { var scroller = (ScrollViewer)sender; - var focusedElement = FocusManager.GetFocusedElement(); + object focusedElement; + if (ApiInformationHelper.IsXamlRootAvailable && scroller.XamlRoot != null) + { + focusedElement = FocusManager.GetFocusedElement(scroller.XamlRoot); + } + else + { + focusedElement = FocusManager.GetFocusedElement(); + } if (focusedElement is UIElement element) { diff --git a/Microsoft.Toolkit.Uwp.UI.Controls.DataGrid/DataGrid/DataGrid.cs b/Microsoft.Toolkit.Uwp.UI.Controls.DataGrid/DataGrid/DataGrid.cs index 67e8e365804..0f88d1b7a05 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls.DataGrid/DataGrid/DataGrid.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls.DataGrid/DataGrid/DataGrid.cs @@ -5730,7 +5730,7 @@ private void DataGrid_LostFocus(object sender, RoutedEventArgs e) // Walk up the visual tree of the newly focused element // to determine if focus is still within DataGrid. - object focusedObject = FocusManager.GetFocusedElement(); + object focusedObject = GetFocusedElement(); DependencyObject focusedDependencyObject = focusedObject as DependencyObject; while (focusedDependencyObject != null) @@ -5796,6 +5796,18 @@ private void DataGrid_LostFocus(object sender, RoutedEventArgs e) } } + private object GetFocusedElement() + { + if (TypeHelper.IsXamlRootAvailable && XamlRoot != null) + { + return FocusManager.GetFocusedElement(XamlRoot); + } + else + { + return FocusManager.GetFocusedElement(); + } + } + private void DataGrid_PointerEntered(object sender, PointerRoutedEventArgs e) { if (e.Pointer.PointerDeviceType != PointerDeviceType.Touch) @@ -6001,7 +6013,7 @@ private bool EndCellEdit(DataGridEditAction editAction, bool exitEditingMode, bo // TODO: Figure out if we should restore a cached this.IsTabStop. this.IsTabStop = true; - if (keepFocus && editingElement.ContainsFocusedElement()) + if (keepFocus && editingElement.ContainsFocusedElement(this)) { this.Focus(FocusState.Programmatic); } @@ -6240,7 +6252,7 @@ private void FlushCurrentCellChanged() _previousAutomationFocusCoordinates = new DataGridCellCoordinates(this.CurrentCellCoordinates); // If the DataGrid itself has focus, we want to move automation focus to the new current element - object focusedObject = FocusManager.GetFocusedElement(); + object focusedObject = GetFocusedElement(); if (focusedObject == this && AutomationPeer.ListenerExists(AutomationEvents.AutomationFocusChanged)) { peer.RaiseAutomationFocusChangedEvent(this.CurrentSlot, this.CurrentColumnIndex); @@ -6295,7 +6307,7 @@ private bool FocusEditingCell(bool setFocus) DataGridCell dataGridCell = this.EditingRow.Cells[_editingColumnIndex]; if (setFocus) { - if (dataGridCell.ContainsFocusedElement()) + if (dataGridCell.ContainsFocusedElement(this)) { success = true; } @@ -7058,7 +7070,7 @@ private bool ProcessEnterKey(bool shift, bool ctrl) } // If Enter was used by a TextBox, we shouldn't handle the key - TextBox focusedTextBox = FocusManager.GetFocusedElement() as TextBox; + TextBox focusedTextBox = GetFocusedElement() as TextBox; if (focusedTextBox != null && focusedTextBox.AcceptsReturn) { return false; diff --git a/Microsoft.Toolkit.Uwp.UI.Controls.DataGrid/Utilities/Extensions.cs b/Microsoft.Toolkit.Uwp.UI.Controls.DataGrid/Utilities/Extensions.cs index 57cfb82a93c..6ed5ef1ad41 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls.DataGrid/Utilities/Extensions.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls.DataGrid/Utilities/Extensions.cs @@ -68,10 +68,23 @@ internal static bool ContainsChild(this DependencyObject element, DependencyObje /// the currently focused element, which is updated synchronously. /// /// Parent DependencyObject + /// Parent UIElement. Used to query the element's XamlRoot. /// True if the currently focused element is within the visual tree of the parent - internal static bool ContainsFocusedElement(this DependencyObject element) + internal static bool ContainsFocusedElement(this DependencyObject element, UIElement uiElement) { - return (element == null) ? false : element.ContainsChild(FocusManager.GetFocusedElement() as DependencyObject); + return (element == null) ? false : element.ContainsChild(GetFocusedElement(uiElement) as DependencyObject); + } + + private static object GetFocusedElement(UIElement uiElement) + { + if (TypeHelper.IsXamlRootAvailable && uiElement.XamlRoot != null) + { + return FocusManager.GetFocusedElement(uiElement.XamlRoot); + } + else + { + return FocusManager.GetFocusedElement(); + } } /// diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/Carousel/Carousel.cs b/Microsoft.Toolkit.Uwp.UI.Controls/Carousel/Carousel.cs index 55380f4b963..88a948539b0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/Carousel/Carousel.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/Carousel/Carousel.cs @@ -257,7 +257,17 @@ private static void OnCarouselPropertyChanged(DependencyObject d, DependencyProp private void FocusContainerFromIndex(int index) { - var oldElem = FocusManager.GetFocusedElement() as ContentControl; + ContentControl oldElem; + + if (ControlHelpers.IsXamlRootAvailable && XamlRoot != null) + { + oldElem = FocusManager.GetFocusedElement(XamlRoot) as ContentControl; + } + else + { + oldElem = FocusManager.GetFocusedElement() as ContentControl; + } + var newElem = ContainerFromIndex(index) as ContentControl; if (oldElem == newElem) diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/Menu/Menu.Events.cs b/Microsoft.Toolkit.Uwp.UI.Controls/Menu/Menu.Events.cs index fba628da34e..390a385c48a 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/Menu/Menu.Events.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/Menu/Menu.Events.cs @@ -119,7 +119,15 @@ private void CoreWindow_KeyDown(CoreWindow sender, KeyEventArgs args) private void Menu_LostFocus(object sender, RoutedEventArgs e) { - var menuItem = FocusManager.GetFocusedElement() as MenuItem; + MenuItem menuItem; + if (ControlHelpers.IsXamlRootAvailable && XamlRoot != null) + { + menuItem = FocusManager.GetFocusedElement(XamlRoot) as MenuItem; + } + else + { + menuItem = FocusManager.GetFocusedElement() as MenuItem; + } if (AllowTooltip) { @@ -145,7 +153,14 @@ private void Dispatcher_AcceleratorKeyActivated(CoreDispatcher sender, Accelerat return; } - _lastFocusElement = FocusManager.GetFocusedElement() as Control; + if (ControlHelpers.IsXamlRootAvailable && XamlRoot != null) + { + _lastFocusElement = FocusManager.GetFocusedElement(XamlRoot) as Control; + } + else + { + _lastFocusElement = FocusManager.GetFocusedElement() as Control; + } if (args.KeyStatus.ScanCode != AltScanCode) { diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/Menu/Menu.Logic.cs b/Microsoft.Toolkit.Uwp.UI.Controls/Menu/Menu.Logic.cs index 12768168ffd..296f5d7cfb5 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/Menu/Menu.Logic.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/Menu/Menu.Logic.cs @@ -30,7 +30,15 @@ public partial class Menu private static bool NavigateUsingKeyboard(KeyEventArgs args, Menu menu, Orientation orientation) { - var element = FocusManager.GetFocusedElement(); + object element; + if (ControlHelpers.IsXamlRootAvailable && menu.XamlRoot != null) + { + element = FocusManager.GetFocusedElement(menu.XamlRoot); + } + else + { + element = FocusManager.GetFocusedElement(); + } if (element is MenuFlyoutPresenter && ((args.VirtualKey == VirtualKey.Down) || diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/OrbitView/OrbitView.cs b/Microsoft.Toolkit.Uwp.UI.Controls/OrbitView/OrbitView.cs index 4cd44307cfc..15d504178ab 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/OrbitView/OrbitView.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/OrbitView/OrbitView.cs @@ -538,7 +538,7 @@ private void OrbitView_KeyDown(object sender, KeyRoutedEventArgs e) if (e.Key == Windows.System.VirtualKey.Left) { e.Handled = true; - if (FocusManager.GetFocusedElement() is ContentControl currentEllement) + if (GetFocusedElement() is ContentControl currentEllement) { var index = ItemsPanelRoot.Children.IndexOf(currentEllement); var nextIndex = (index + 1) % Items.Count; @@ -549,7 +549,7 @@ private void OrbitView_KeyDown(object sender, KeyRoutedEventArgs e) else if (e.Key == Windows.System.VirtualKey.Right) { e.Handled = true; - if (FocusManager.GetFocusedElement() is ContentControl currentEllement) + if (GetFocusedElement() is ContentControl currentEllement) { var index = ItemsPanelRoot.Children.IndexOf(currentEllement); var nextIndex = index > 0 ? index - 1 : Items.Count - 1; @@ -559,6 +559,18 @@ private void OrbitView_KeyDown(object sender, KeyRoutedEventArgs e) } } + private object GetFocusedElement() + { + if (ControlHelpers.IsXamlRootAvailable && XamlRoot != null) + { + return FocusManager.GetFocusedElement(XamlRoot); + } + else + { + return FocusManager.GetFocusedElement(); + } + } + private void OnItemClicked(OrbitViewItem item) { if (IsItemClickEnabled) diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/TextToolbar/ToolbarItems/Common/CommonButtons.Events.cs b/Microsoft.Toolkit.Uwp.UI.Controls/TextToolbar/ToolbarItems/Common/CommonButtons.Events.cs index f5251b7cd72..89971602e55 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/TextToolbar/ToolbarItems/Common/CommonButtons.Events.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/TextToolbar/ToolbarItems/Common/CommonButtons.Events.cs @@ -87,13 +87,20 @@ public async void OpenLinkCreator(ToolbarButton button) selection.GetText(Windows.UI.Text.TextGetOptions.FormatRtf, out string labeltext); labelBox.Document.SetText(Windows.UI.Text.TextSetOptions.FormatRtf, labeltext); - var result = await new ContentDialog + var contentDialog = new ContentDialog { Title = StringExtensions.GetLocalized("TextToolbarStrings_CreateLinkLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"), Content = contentPanel, PrimaryButtonText = StringExtensions.GetLocalized("TextToolbarStrings_OkLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"), SecondaryButtonText = StringExtensions.GetLocalized("TextToolbarStrings_CancelLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources") - }.ShowAsync(); + }; + + if (ControlHelpers.IsXamlRootAvailable && button.XamlRoot != null) + { + contentDialog.XamlRoot = button.XamlRoot; + } + + var result = await contentDialog.ShowAsync(); if (result == ContentDialogResult.Primary) { @@ -107,7 +114,7 @@ public async void OpenLinkCreator(ToolbarButton button) if (string.IsNullOrWhiteSpace(linkText)) { - ShowContentDialog(warningLabel, linkInvalidLabel, okLabel); + ShowContentDialog(warningLabel, linkInvalidLabel, okLabel, button); return; } @@ -116,7 +123,7 @@ public async void OpenLinkCreator(ToolbarButton button) var wellFormed = Uri.IsWellFormedUriString(linkText, relativeBox?.IsChecked == true ? UriKind.RelativeOrAbsolute : UriKind.Absolute); if (!wellFormed) { - ShowContentDialog(warningLabel, linkInvalidLabel, okLabel); + ShowContentDialog(warningLabel, linkInvalidLabel, okLabel, button); return; } } @@ -125,20 +132,21 @@ public async void OpenLinkCreator(ToolbarButton button) } } - /// - /// Opens a to notify the user about empty and whitespace inputs. - /// - /// The - /// The of the ContentDialog - /// The content of the primary button - private async void ShowContentDialog(string title, string content, string primaryButtonText) + private async void ShowContentDialog(string title, string content, string primaryButtonText, ToolbarButton button) { - await new ContentDialog + var contentDialog = new ContentDialog { Title = title, Content = content, PrimaryButtonText = primaryButtonText - }.ShowAsync(); + }; + + if (ControlHelpers.IsXamlRootAvailable && button.XamlRoot != null) + { + contentDialog.XamlRoot = button.XamlRoot; + } + + await contentDialog.ShowAsync(); } } } \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.Selection.cs b/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.Selection.cs index 8af4402d691..c952b2defc0 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.Selection.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.Selection.cs @@ -33,7 +33,7 @@ private enum MoveDirection private bool MoveFocusAndSelection(MoveDirection direction) { bool retVal = false; - var currentContainerItem = FocusManager.GetFocusedElement() as TokenizingTextBoxItem; + var currentContainerItem = GetCurrentContainerItem(); if (currentContainerItem != null) { @@ -123,6 +123,18 @@ private bool MoveFocusAndSelection(MoveDirection direction) return retVal; } + private TokenizingTextBoxItem GetCurrentContainerItem() + { + if (ControlHelpers.IsXamlRootAvailable && XamlRoot != null) + { + return FocusManager.GetFocusedElement(XamlRoot) as TokenizingTextBoxItem; + } + else + { + return FocusManager.GetFocusedElement() as TokenizingTextBoxItem; + } + } + internal void SelectAllTokensAndText() { _ = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => @@ -245,7 +257,7 @@ private async void TokenizingTextBoxItem_ClearClicked(TokenizingTextBoxItem send /// async task internal async Task RemoveAllSelectedTokens() { - var currentContainerItem = FocusManager.GetFocusedElement() as TokenizingTextBoxItem; + var currentContainerItem = GetCurrentContainerItem(); while (SelectedItems.Count > 0) { diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.cs b/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.cs index 2ae42064286..bbcf95fb5e4 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls/TokenizingTextBox/TokenizingTextBox.cs @@ -99,7 +99,12 @@ private void TokenizingTextBox_ItemClick(object sender, ItemClickEventArgs e) private void TokenizingTextBox_PreviewKeyUp(object sender, KeyRoutedEventArgs e) { - switch (e.Key) + TokenizingTextBox_PreviewKeyUp(e.Key); + } + + internal void TokenizingTextBox_PreviewKeyUp(VirtualKey key) + { + switch (key) { case VirtualKey.Escape: { @@ -123,15 +128,20 @@ private void FocusPrimaryAutoSuggestBox() } private async void TokenizingTextBox_PreviewKeyDown(object sender, KeyRoutedEventArgs e) + { + e.Handled = await TokenizingTextBox_PreviewKeyDown(e.Key); + } + + internal async Task TokenizingTextBox_PreviewKeyDown(VirtualKey key) { // Global handlers on control regardless if focused on item or in textbox. - switch (e.Key) + switch (key) { case VirtualKey.C: if (IsControlPressed) { CopySelectedToClipboard(); - e.Handled = true; + return true; } break; @@ -148,24 +158,24 @@ private async void TokenizingTextBox_PreviewKeyDown(object sender, KeyRoutedEven break; // For moving between tokens - case Windows.System.VirtualKey.Left: - e.Handled = MoveFocusAndSelection(MoveDirection.Previous); - break; + case VirtualKey.Left: + return MoveFocusAndSelection(MoveDirection.Previous); - case Windows.System.VirtualKey.Right: - e.Handled = MoveFocusAndSelection(MoveDirection.Next); - break; + case VirtualKey.Right: + return MoveFocusAndSelection(MoveDirection.Next); case VirtualKey.A: // modify the select-all behaviour to ensure the text in the edit box gets selected. if (IsControlPressed) { this.SelectAllTokensAndText(); - e.Handled = true; + return true; } break; } + + return false; } /// @@ -207,7 +217,7 @@ private async void TokenizingTextBox_CharacterReceived(UIElement sender, Charact { var container = ContainerFromItem(_currentTextEdit) as TokenizingTextBoxItem; - if (container != null && !(FocusManager.GetFocusedElement().Equals(container._autoSuggestTextBox) || char.IsControl(args.Character))) + if (container != null && !(GetFocusedElement().Equals(container._autoSuggestTextBox) || char.IsControl(args.Character))) { if (SelectedItems.Count > 0) { @@ -288,6 +298,18 @@ void WaitForLoad(object s, RoutedEventArgs eargs) } } + private object GetFocusedElement() + { + if (ControlHelpers.IsXamlRootAvailable && XamlRoot != null) + { + return FocusManager.GetFocusedElement(XamlRoot); + } + else + { + return FocusManager.GetFocusedElement(); + } + } + #region ItemsControl Container Methods /// diff --git a/UnitTests/UnitTests.XamlIslands.UWPApp/UnitTests.XamlIslands.UWPApp.csproj b/UnitTests/UnitTests.XamlIslands.UWPApp/UnitTests.XamlIslands.UWPApp.csproj index 3a3ad5d52a0..5d4f2ab6393 100644 --- a/UnitTests/UnitTests.XamlIslands.UWPApp/UnitTests.XamlIslands.UWPApp.csproj +++ b/UnitTests/UnitTests.XamlIslands.UWPApp/UnitTests.XamlIslands.UWPApp.csproj @@ -133,6 +133,8 @@ TestsPage.xaml + + diff --git a/UnitTests/UnitTests.XamlIslands.UWPApp/XamlIslandsTest_TextToolbar.cs b/UnitTests/UnitTests.XamlIslands.UWPApp/XamlIslandsTest_TextToolbar.cs new file mode 100644 index 00000000000..3d0a1a09bb8 --- /dev/null +++ b/UnitTests/UnitTests.XamlIslands.UWPApp/XamlIslandsTest_TextToolbar.cs @@ -0,0 +1,78 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using Microsoft.Toolkit.Uwp.Helpers; +using Microsoft.Toolkit.Uwp.UI.Controls; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; + +namespace UnitTests.XamlIslands.UWPApp +{ + [STATestClass] + public partial class XamlIslandsTest_TextToolbar + { + private TextToolbar _textToolbar; + + [TestInitialize] + public async Task Init() + { + await App.Dispatcher.ExecuteOnUIThreadAsync(() => + { + var richEditBox = new RichEditBox + { + PlaceholderText = "Enter Text Here", + TextWrapping = TextWrapping.Wrap, + VerticalContentAlignment = VerticalAlignment.Stretch, + MinHeight = 300, + BorderThickness = new Thickness(1), + SelectionFlyout = null + }; + + _textToolbar = new TextToolbar + { + Editor = richEditBox, + IsEnabled = true, + Format = Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarFormats.Format.RichText + }; + + var grid = new Grid + { + Children = + { + _textToolbar, + richEditBox + }, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + Height = 200, + Width = 300 + }; + grid.RowDefinitions.Add(new RowDefinition + { + Height = GridLength.Auto + }); + grid.RowDefinitions.Add(new RowDefinition()); + TestsPage.Instance.SetMainTestContent(grid); + Grid.SetRow(richEditBox, 1); + }); + } + + [TestMethod] + public async Task TextToobar_PopupShowsInCorrectXamlRoot() + { + await App.Dispatcher.ExecuteOnUIThreadAsync(async () => + { + await Task.Delay(500); + + var args = new ShortcutKeyRequestArgs(Windows.System.VirtualKey.K, false, null); + + _textToolbar.GetDefaultButton(Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.ButtonType.Link).ShortcutRequested(ref args); + + await Task.Delay(10000); + }); + } + } +} \ No newline at end of file diff --git a/UnitTests/UnitTests.XamlIslands.UWPApp/XamlIslandsTest_TokenizingTextBox.cs b/UnitTests/UnitTests.XamlIslands.UWPApp/XamlIslandsTest_TokenizingTextBox.cs new file mode 100644 index 00000000000..dcb60f0f4bd --- /dev/null +++ b/UnitTests/UnitTests.XamlIslands.UWPApp/XamlIslandsTest_TokenizingTextBox.cs @@ -0,0 +1,155 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Toolkit.Uwp.Helpers; +using Microsoft.Toolkit.Uwp.UI; +using Microsoft.Toolkit.Uwp.UI.Controls; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Markup; + +namespace UnitTests.XamlIslands.UWPApp +{ + [STATestClass] + public partial class XamlIslandsTest_TokenizingTextBox + { + private TokenizingTextBox _tokenizingTextBox; + private AdvancedCollectionView _acv; + + public class SampleDataType + { + public Symbol Icon { get; set; } + + public string Text { get; set; } + + public override string ToString() + { + return Text; + } + } + + private readonly List _samples = new List() + { + new SampleDataType() { Text = "Account", Icon = Symbol.Account }, + new SampleDataType() { Text = "Add Friend", Icon = Symbol.AddFriend }, + new SampleDataType() { Text = "Attach", Icon = Symbol.Attach }, + new SampleDataType() { Text = "Attach Camera", Icon = Symbol.AttachCamera }, + new SampleDataType() { Text = "Audio", Icon = Symbol.Audio }, + new SampleDataType() { Text = "Block Contact", Icon = Symbol.BlockContact }, + new SampleDataType() { Text = "Calculator", Icon = Symbol.Calculator }, + new SampleDataType() { Text = "Calendar", Icon = Symbol.Calendar }, + new SampleDataType() { Text = "Camera", Icon = Symbol.Camera }, + new SampleDataType() { Text = "Contact", Icon = Symbol.Contact }, + new SampleDataType() { Text = "Favorite", Icon = Symbol.Favorite }, + new SampleDataType() { Text = "Link", Icon = Symbol.Link }, + new SampleDataType() { Text = "Mail", Icon = Symbol.Mail }, + new SampleDataType() { Text = "Map", Icon = Symbol.Map }, + new SampleDataType() { Text = "Phone", Icon = Symbol.Phone }, + new SampleDataType() { Text = "Pin", Icon = Symbol.Pin }, + new SampleDataType() { Text = "Rotate", Icon = Symbol.Rotate }, + new SampleDataType() { Text = "Rotate Camera", Icon = Symbol.RotateCamera }, + new SampleDataType() { Text = "Send", Icon = Symbol.Send }, + new SampleDataType() { Text = "Tags", Icon = Symbol.Tag }, + new SampleDataType() { Text = "UnFavorite", Icon = Symbol.UnFavorite }, + new SampleDataType() { Text = "UnPin", Icon = Symbol.UnPin }, + new SampleDataType() { Text = "Zoom", Icon = Symbol.Zoom }, + new SampleDataType() { Text = "ZoomIn", Icon = Symbol.ZoomIn }, + new SampleDataType() { Text = "ZoomOut", Icon = Symbol.ZoomOut }, + }; + + [TestInitialize] + public async Task Init() + { + await App.Dispatcher.ExecuteOnUIThreadAsync(() => + { + _acv = new AdvancedCollectionView(_samples, false); + + _acv.SortDescriptions.Add(new SortDescription(nameof(SampleDataType.Text), SortDirection.Ascending)); + + var xamlTokenizingTextBox = @" + + + + + + + + + + + + + + + + + "; + + _tokenizingTextBox = XamlReader.Load(xamlTokenizingTextBox) as TokenizingTextBox; + _tokenizingTextBox.SuggestedItemsSource = _acv; + + TestsPage.Instance.SetMainTestContent(_tokenizingTextBox); + + _tokenizingTextBox.AddTokenItem(_samples[0], true); + _tokenizingTextBox.AddTokenItem(_samples[1], true); + _tokenizingTextBox.AddTokenItem(_samples[2], true); + }); + } + + [TestMethod] + public async Task TokenizingTextBox_GetFocusedElement_RemoveAllSelectedTokens() + { + await App.Dispatcher.ExecuteOnUIThreadAsync(async () => + { + await Task.Delay(500); + + _tokenizingTextBox.SelectedIndex = 1; + + await Task.Delay(500); + + await _tokenizingTextBox.TokenizingTextBox_PreviewKeyDown(Windows.System.VirtualKey.Left); + + await Task.Delay(500); + + Assert.AreEqual(4, _tokenizingTextBox.Items.Count); + + await _tokenizingTextBox.RemoveAllSelectedTokens(); + + await Task.Delay(500); + + Assert.AreEqual(3, _tokenizingTextBox.Items.Count); + }); + } + + [TestMethod] + public async Task TokenizingTextBox_PopupShowsInCorrectXamlRoot() + { + await App.Dispatcher.ExecuteOnUIThreadAsync(async () => + { + await Task.Delay(500); + + _tokenizingTextBox.SelectedIndex = 1; + + await Task.Delay(500); + + await _tokenizingTextBox.TokenizingTextBox_PreviewKeyDown(Windows.System.VirtualKey.Left); + + var tokenizingTextBoxItem = _tokenizingTextBox.ContainerFromItem(_tokenizingTextBox.SelectedItem) as TokenizingTextBoxItem; + tokenizingTextBoxItem.ContextFlyout.ShowAt(tokenizingTextBoxItem); + + await Task.Delay(1000); + }); + } + } +} \ No newline at end of file