зеркало из https://github.com/DeGsoft/maui-linux.git
[WinRT/UWP] Enable selection in password entry (#677)
* [WinRT/UWP] Enable selection in password entry * Remove unnecessary if
This commit is contained in:
Родитель
e3d213cbe7
Коммит
90582e9777
|
@ -0,0 +1,50 @@
|
||||||
|
using Xamarin.Forms.CustomAttributes;
|
||||||
|
using Xamarin.Forms.Internals;
|
||||||
|
|
||||||
|
#if UITEST
|
||||||
|
using Xamarin.UITest;
|
||||||
|
using NUnit.Framework;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Xamarin.Forms.Controls.Issues
|
||||||
|
{
|
||||||
|
[Preserve(AllMembers = true)]
|
||||||
|
[Issue(IssueTracker.Bugzilla, 45277, "[WinRT/UWP] Entry with IsPassword = true does not allow selection of characters", PlatformAffected.WinRT)]
|
||||||
|
public class Bugzilla45277 : TestContentPage
|
||||||
|
{
|
||||||
|
protected override void Init()
|
||||||
|
{
|
||||||
|
var passwordTextLabel = new Label
|
||||||
|
{
|
||||||
|
Text = "[No Password Text Yet]"
|
||||||
|
};
|
||||||
|
var passwordEntry = new Entry
|
||||||
|
{
|
||||||
|
IsPassword = true,
|
||||||
|
Placeholder = "Enter password"
|
||||||
|
};
|
||||||
|
passwordEntry.Completed += (sender, args) => DisplayAlert("Enter pressed", "OK", "Cancel");
|
||||||
|
passwordEntry.TextChanged += (sender, args) =>
|
||||||
|
{
|
||||||
|
passwordTextLabel.Text = passwordEntry.Text;
|
||||||
|
};
|
||||||
|
|
||||||
|
Content = new StackLayout
|
||||||
|
{
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new Label
|
||||||
|
{
|
||||||
|
Text = "The below label should allow Paste and Select All commands; however, copying via keyboard should not work."
|
||||||
|
},
|
||||||
|
passwordEntry,
|
||||||
|
new Entry
|
||||||
|
{
|
||||||
|
Placeholder = "Entry for easily testing your paste functionality"
|
||||||
|
},
|
||||||
|
passwordTextLabel
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -173,6 +173,7 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla45027.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla45027.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla45330.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla45330.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla44955.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla44955.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla45277.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla45743.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla45743.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla46458.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla46458.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla46494.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla46494.cs" />
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Windows.System;
|
||||||
using Windows.UI.Core;
|
using Windows.UI.Core;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
|
@ -44,6 +45,7 @@ namespace Xamarin.Forms.Platform.WinRT
|
||||||
bool _cachedSpellCheckSetting;
|
bool _cachedSpellCheckSetting;
|
||||||
CancellationTokenSource _cts;
|
CancellationTokenSource _cts;
|
||||||
bool _internalChangeFlag;
|
bool _internalChangeFlag;
|
||||||
|
int _cachedSelectionLength;
|
||||||
|
|
||||||
public FormsTextBox()
|
public FormsTextBox()
|
||||||
{
|
{
|
||||||
|
@ -237,19 +239,61 @@ namespace Xamarin.Forms.Platform.WinRT
|
||||||
|
|
||||||
void OnSelectionChanged(object sender, RoutedEventArgs routedEventArgs)
|
void OnSelectionChanged(object sender, RoutedEventArgs routedEventArgs)
|
||||||
{
|
{
|
||||||
if (!IsPassword)
|
// Cache this value for later use as explained in OnKeyDown below
|
||||||
{
|
_cachedSelectionLength = SelectionLength;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent the user from selecting any text in the password box by forcing all selection
|
// Because the implementation of a password entry is based around inheriting from TextBox (via FormsTextBox), there
|
||||||
// to zero-length at the end of the Text
|
// are some inaccuracies in the behavior. OnKeyDown is what needs to be used for a workaround in this case because
|
||||||
// This simulates the "do not allow clipboard copy" behavior the PasswordBox control has
|
// there's no easy way to disable specific keyboard shortcuts in a TextBox, so key presses are being intercepted and
|
||||||
if (SelectionLength > 0 || SelectionStart < Text.Length)
|
// handled accordingly.
|
||||||
|
protected override void OnKeyDown(KeyRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (IsPassword)
|
||||||
{
|
{
|
||||||
SelectionLength = 0;
|
// The ctrlDown flag is used to track if the Ctrl key is pressed; if it's actively being used and the most recent
|
||||||
SelectionStart = Text.Length;
|
// key to trigger OnKeyDown, then treat it as handled.
|
||||||
|
var ctrlDown = Window.Current.CoreWindow.GetKeyState(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
|
||||||
|
|
||||||
|
// The shift, tab, and directional (Home/End/PgUp/PgDown included) keys can be used to select text and should otherwise
|
||||||
|
// be ignored.
|
||||||
|
if (
|
||||||
|
e.Key == VirtualKey.Shift ||
|
||||||
|
e.Key == VirtualKey.Tab ||
|
||||||
|
e.Key == VirtualKey.Left ||
|
||||||
|
e.Key == VirtualKey.Right ||
|
||||||
|
e.Key == VirtualKey.Up ||
|
||||||
|
e.Key == VirtualKey.Down ||
|
||||||
|
e.Key == VirtualKey.Home ||
|
||||||
|
e.Key == VirtualKey.End ||
|
||||||
|
e.Key == VirtualKey.PageUp ||
|
||||||
|
e.Key == VirtualKey.PageDown)
|
||||||
|
{
|
||||||
|
base.OnKeyDown(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// For anything else, continue on (calling base.OnKeyDown) and then if Ctrl is still being pressed, do nothing about it.
|
||||||
|
// The tricky part here is that the SelectionLength value needs to be cached because in an example where the user entered
|
||||||
|
// '123' into the field and selects all of it, the moment that any character key is pressed to replace the entire string,
|
||||||
|
// the SelectionLength is equal to zero, which is not what's desired. Entering a key will thus remove the selected number
|
||||||
|
// of characters from the Text value. OnKeyDown is fortunately called before OnSelectionChanged which enables this.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the C or X keys (copy/cut) are pressed while Ctrl is active, ignore handing them at all. Undo and Redo (Z/Y) should
|
||||||
|
// be ignored as well as this emulates the regular behavior of a PasswordBox.
|
||||||
|
if ((e.Key == VirtualKey.C || e.Key == VirtualKey.X || e.Key == VirtualKey.Z || e.Key == VirtualKey.Y) && ctrlDown)
|
||||||
|
{
|
||||||
|
e.Handled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnKeyDown(e);
|
||||||
|
if (_cachedSelectionLength > 0 && !ctrlDown)
|
||||||
|
Text = Text.Remove(SelectionStart, _cachedSelectionLength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
base.OnKeyDown(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnTextChanged(object sender, Windows.UI.Xaml.Controls.TextChangedEventArgs textChangedEventArgs)
|
void OnTextChanged(object sender, Windows.UI.Xaml.Controls.TextChangedEventArgs textChangedEventArgs)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче