From 5001460dd25ccaf8f31d77bc8b0d4960497f2b9c Mon Sep 17 00:00:00 2001 From: Almir Vuk Date: Thu, 10 Jan 2019 17:21:29 +0100 Subject: [PATCH] [Enhancement] Entry: Read-only Entry and Editor (#1972) - fixes #1678 - fixes #4834 * InputView BindableProperty IsReadOnly * Android Editor and Entry setup * MacOS Editor and Entry setup * Tizen Editor and Entry setup * UAP Editor and Entry setup * WPF Editor and Entry setup * iOS Editor and Entry setup * Issue1678 - TestContentPage added * Tests added * Tizen Editor and Entry fix * UI Test fix * Android fix for Entry and Editor. * Unit Tests fix. * Android Renderer first try. * MacOS Entry renderer small fix. * UpdateEditable fix. * Android Entry and Editor reduced number of calls to BP. * fix TestAttributes conflicts * Remove keyboard * [macOS] relinquish first responder * [Android] remove call to UpdateCursorSelection * [UWP] fix tabs --- .../Issue1678.cs | 51 ++++++++++++++++++++++ .../Xamarin.Forms.Controls.Issues.Shared.projitems | 1 + .../CoreGalleryPages/EditorCoreGalleryPage.cs | 3 ++ .../CoreGalleryPages/EntryCoreGalleryPage.cs | 2 + Xamarin.Forms.Core.UnitTests/EditorTests.cs | 14 ++++++ Xamarin.Forms.Core.UnitTests/EntryUnitTests.cs | 15 +++++++ .../NotifiedPropertiesTests.cs | 4 +- Xamarin.Forms.Core/InputView.cs | 8 ++++ Xamarin.Forms.CustomAttributes/TestAttributes.cs | 4 ++ .../Renderers/EditorRenderer.cs | 12 +++++ .../Renderers/EntryRenderer.cs | 16 ++++++- .../Renderers/EditorRenderer.cs | 10 +++++ .../Renderers/EntryRenderer.cs | 13 +++++- .../Renderers/EditorRenderer.cs | 6 +++ .../Renderers/EntryRenderer.cs | 6 +++ Xamarin.Forms.Platform.UAP/EditorRenderer.cs | 8 ++++ Xamarin.Forms.Platform.UAP/EntryRenderer.cs | 8 ++++ .../Renderers/EditorRenderer.cs | 8 ++++ .../Renderers/EntryRenderer.cs | 8 ++++ .../Renderers/EditorRenderer.cs | 19 +++++++- .../Renderers/EntryRenderer.cs | 10 ++++- 21 files changed, 219 insertions(+), 7 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue1678.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue1678.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue1678.cs new file mode 100644 index 0000000..45aebfa --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue1678.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +namespace Xamarin.Forms.Controls.Issues +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 1678, "[Enhancement] Entry: Read-only entry", PlatformAffected.All)] + public class Issue1678 + : TestContentPage + { + protected override void Init() + { + var entryText = "Entry Lorem Ipsum"; + var editorText = "Editor Lorem Ipsum"; + + var entryDefaults = new Entry { Text = entryText }; + var editorDefaults = new Editor { Text = editorText }; + var entryReadOnly = new Entry { Text = entryText, IsReadOnly = true }; + var editorReadOnly = new Editor { Text = editorText, IsReadOnly = true }; + var entryToggleable = new Entry { Text = entryText }; + var editorToggleable = new Editor { Text = editorText }; + + var toggle = new Switch { IsToggled = false }; + + var stackLayout = new StackLayout(); + stackLayout.Children.Add(new Label { Text = "Defaults" }); + stackLayout.Children.Add(entryDefaults); + stackLayout.Children.Add(editorDefaults); + stackLayout.Children.Add(new Label { Text = "Read Only" }); + stackLayout.Children.Add(entryReadOnly); + stackLayout.Children.Add(editorReadOnly); + stackLayout.Children.Add(new Label { Text = "Toggleable is read only" }); + stackLayout.Children.Add(entryToggleable); + stackLayout.Children.Add(editorToggleable); + stackLayout.Children.Add(toggle); + + toggle.Toggled += (_, b) => + { + entryToggleable.IsReadOnly = b.Value; + editorToggleable.IsReadOnly = b.Value; + }; + + stackLayout.Padding = new Thickness(0, 20, 0, 0); + Content = stackLayout; + } + } +} diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index f5c9c8a..78e8d92 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -35,6 +35,7 @@ + diff --git a/Xamarin.Forms.Controls/CoreGalleryPages/EditorCoreGalleryPage.cs b/Xamarin.Forms.Controls/CoreGalleryPages/EditorCoreGalleryPage.cs index b8ba817..2f961e5 100644 --- a/Xamarin.Forms.Controls/CoreGalleryPages/EditorCoreGalleryPage.cs +++ b/Xamarin.Forms.Controls/CoreGalleryPages/EditorCoreGalleryPage.cs @@ -40,6 +40,8 @@ namespace Xamarin.Forms.Controls var maxLengthContainer = new ViewContainer(Test.InputView.MaxLength, new Editor { MaxLength = 3 }); + var readOnlyContainer = new ViewContainer(Test.Editor.IsReadOnly, new Editor { Text = "This is read-only Editor", IsReadOnly = true }); + Add(completedContainer); Add(textContainer); Add(textChangedContainer); @@ -54,6 +56,7 @@ namespace Xamarin.Forms.Controls Add(textColorDisabledContainer); Add(keyboardContainer); Add(maxLengthContainer); + Add(readOnlyContainer); } } } \ No newline at end of file diff --git a/Xamarin.Forms.Controls/CoreGalleryPages/EntryCoreGalleryPage.cs b/Xamarin.Forms.Controls/CoreGalleryPages/EntryCoreGalleryPage.cs index 67bc5cd..8368f08 100644 --- a/Xamarin.Forms.Controls/CoreGalleryPages/EntryCoreGalleryPage.cs +++ b/Xamarin.Forms.Controls/CoreGalleryPages/EntryCoreGalleryPage.cs @@ -66,6 +66,7 @@ namespace Xamarin.Forms.Controls var maxLengthContainer = new ViewContainer(Test.InputView.MaxLength, new Entry { MaxLength = 3 }); + var readOnlyContainer = new ViewContainer(Test.Entry.IsReadOnly, new Entry { Text = "This is read-only Entry", IsReadOnly = true }); var isPasswordInputScopeContainer = new ViewContainer(Test.Entry.IsPasswordNumeric, new Entry { Keyboard = Keyboard.Numeric }); var switchPasswordButton = new Button { @@ -110,6 +111,7 @@ namespace Xamarin.Forms.Controls Add (placeholderColorDisabledContainer); Add (passwordColorContainer); Add (maxLengthContainer); + Add (readOnlyContainer); Add (isPasswordInputScopeContainer); } } diff --git a/Xamarin.Forms.Core.UnitTests/EditorTests.cs b/Xamarin.Forms.Core.UnitTests/EditorTests.cs index c16f1d2..b4a969b 100644 --- a/Xamarin.Forms.Core.UnitTests/EditorTests.cs +++ b/Xamarin.Forms.Core.UnitTests/EditorTests.cs @@ -30,5 +30,19 @@ namespace Xamarin.Forms.Core.UnitTests Assert.AreEqual (initialText, oldText); Assert.AreEqual (finalText, newText); } + + [TestCase(true)] + public void IsReadOnlyTest(bool isReadOnly) + { + Editor editor = new Editor(); + editor.SetValue(InputView.IsReadOnlyProperty, isReadOnly); + Assert.AreEqual(isReadOnly, editor.IsReadOnly); + } + [Test] + public void IsReadOnlyDefaultValueTest() + { + Editor editor = new Editor(); + Assert.AreEqual(editor.IsReadOnly, false); + } } } diff --git a/Xamarin.Forms.Core.UnitTests/EntryUnitTests.cs b/Xamarin.Forms.Core.UnitTests/EntryUnitTests.cs index 906f697..96eaf5e 100644 --- a/Xamarin.Forms.Core.UnitTests/EntryUnitTests.cs +++ b/Xamarin.Forms.Core.UnitTests/EntryUnitTests.cs @@ -154,5 +154,20 @@ namespace Xamarin.Forms.Core.UnitTests Assert.True(result == isEnabled ? true : false); } + + [TestCase(true)] + public void IsReadOnlyTest(bool isReadOnly) + { + Entry entry = new Entry(); + entry.SetValue(InputView.IsReadOnlyProperty, isReadOnly); + Assert.AreEqual(isReadOnly, entry.IsReadOnly); + } + + [Test] + public void IsReadOnlyDefaultValueTest() + { + Entry entry = new Entry(); + Assert.AreEqual(entry.IsReadOnly, false); + } } } diff --git a/Xamarin.Forms.Core.UnitTests/NotifiedPropertiesTests.cs b/Xamarin.Forms.Core.UnitTests/NotifiedPropertiesTests.cs index bd47c0b..5f4027c 100644 --- a/Xamarin.Forms.Core.UnitTests/NotifiedPropertiesTests.cs +++ b/Xamarin.Forms.Core.UnitTests/NotifiedPropertiesTests.cs @@ -151,7 +151,9 @@ namespace Xamarin.Forms.Core.UnitTests new PropertyTestCase ("NumberOfTapsRequired", t => t.NumberOfTapsRequired, (t, o) => t.NumberOfTapsRequired = o, () => 1, 3), new PropertyTestCase ("CommandParameter", t => t.CommandParameter, (t, o) => t.CommandParameter = o, () => null, "Test"), new PropertyTestCase ("Command", t => t.Command, (t, o) => t.Command = o, () => null, new Command(()=>{})), - new PropertyTestCase ("IsGestureEnabled", md => md.IsGestureEnabled, (md, v) => md.IsGestureEnabled = v, () => true, false) + new PropertyTestCase ("IsGestureEnabled", md => md.IsGestureEnabled, (md, v) => md.IsGestureEnabled = v, () => true, false), + new PropertyTestCase ("IsReadOnly", v => v.IsReadOnly, (v, o) => v.IsReadOnly = o, () => false, true), + new PropertyTestCase ("IsReadOnly", v => v.IsReadOnly, (v, o) => v.IsReadOnly = o, () => false, true) }; #pragma warning restore 0414 diff --git a/Xamarin.Forms.Core/InputView.cs b/Xamarin.Forms.Core/InputView.cs index acb4532..dc5f094 100644 --- a/Xamarin.Forms.Core/InputView.cs +++ b/Xamarin.Forms.Core/InputView.cs @@ -8,6 +8,8 @@ namespace Xamarin.Forms public static readonly BindableProperty MaxLengthProperty = BindableProperty.Create(nameof(MaxLength), typeof(int), typeof(int), int.MaxValue); + public static readonly BindableProperty IsReadOnlyProperty = BindableProperty.Create(nameof(IsReadOnly), typeof(bool), typeof(InputView), false); + public int MaxLength { get { return (int)GetValue(MaxLengthProperty); } @@ -29,5 +31,11 @@ namespace Xamarin.Forms get { return (bool)GetValue(IsSpellCheckEnabledProperty); } set { SetValue(IsSpellCheckEnabledProperty, value); } } + + public bool IsReadOnly + { + get { return (bool)GetValue(IsReadOnlyProperty); } + set { SetValue(IsReadOnlyProperty, value); } + } } } \ No newline at end of file diff --git a/Xamarin.Forms.CustomAttributes/TestAttributes.cs b/Xamarin.Forms.CustomAttributes/TestAttributes.cs index 702a7a1..9ab8f12 100644 --- a/Xamarin.Forms.CustomAttributes/TestAttributes.cs +++ b/Xamarin.Forms.CustomAttributes/TestAttributes.cs @@ -507,6 +507,8 @@ namespace Xamarin.Forms.CustomAttributes FontAttributes, FontFamily, FontSize, + MaxLength, + IsReadOnly } public enum Entry @@ -530,6 +532,8 @@ namespace Xamarin.Forms.CustomAttributes TextDisabledColor, PlaceholderDisabledColor, PasswordColor, + MaxLength, + IsReadOnly, IsPasswordNumeric } diff --git a/Xamarin.Forms.Platform.Android/Renderers/EditorRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/EditorRenderer.cs index f72ef69..b119f55 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/EditorRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/EditorRenderer.cs @@ -90,6 +90,7 @@ namespace Xamarin.Forms.Platform.Android UpdateMaxLength(); UpdatePlaceholderColor(); UpdatePlaceholderText(); + UpdateIsReadOnly(); } protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) @@ -116,6 +117,8 @@ namespace Xamarin.Forms.Platform.Android UpdatePlaceholderText(); else if (e.PropertyName == Editor.PlaceholderColorProperty.PropertyName) UpdatePlaceholderColor(); + else if (e.PropertyName == InputView.IsReadOnlyProperty.PropertyName) + UpdateIsReadOnly(); base.OnElementPropertyChanged(sender, e); } @@ -247,5 +250,14 @@ namespace Xamarin.Forms.Platform.Android if (currentControlText.Length > Element.MaxLength) Control.Text = currentControlText.Substring(0, Element.MaxLength); } + + void UpdateIsReadOnly() + { + bool isReadOnly = !Element.IsReadOnly; + + Control.FocusableInTouchMode = isReadOnly; + Control.Focusable = isReadOnly; + Control.SetCursorVisible(isReadOnly); + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.Android/Renderers/EntryRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/EntryRenderer.cs index b081461..0c7db11 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/EntryRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/EntryRenderer.cs @@ -109,6 +109,7 @@ namespace Xamarin.Forms.Platform.Android UpdateMaxLength(); UpdateImeOptions(); UpdateReturnType(); + UpdateIsReadOnly(); if (_cursorPositionChangePending || _selectionLengthChangePending) UpdateCursorSelection(); @@ -183,6 +184,8 @@ namespace Xamarin.Forms.Platform.Android UpdateCursorSelection(); else if (e.PropertyName == Entry.CursorPositionProperty.PropertyName) UpdateCursorSelection(); + else if (e.PropertyName == InputView.IsReadOnlyProperty.PropertyName) + UpdateIsReadOnly(); base.OnElementPropertyChanged(sender, e); } @@ -332,7 +335,7 @@ namespace Xamarin.Forms.Platform.Android if (_nativeSelectionIsUpdating || Control == null || Element == null) return; - if (Control.RequestFocus()) + if (!Element.IsReadOnly && Control.RequestFocus()) { try { @@ -414,5 +417,14 @@ namespace Xamarin.Forms.Platform.Android _nativeSelectionIsUpdating = false; } } + + void UpdateIsReadOnly() + { + bool isReadOnly = !Element.IsReadOnly; + + Control.FocusableInTouchMode = isReadOnly; + Control.Focusable = isReadOnly; + Control.SetCursorVisible(isReadOnly); + } } -} +} \ No newline at end of file diff --git a/Xamarin.Forms.Platform.MacOS/Renderers/EditorRenderer.cs b/Xamarin.Forms.Platform.MacOS/Renderers/EditorRenderer.cs index 45139c0..771c6c9 100644 --- a/Xamarin.Forms.Platform.MacOS/Renderers/EditorRenderer.cs +++ b/Xamarin.Forms.Platform.MacOS/Renderers/EditorRenderer.cs @@ -42,6 +42,7 @@ namespace Xamarin.Forms.Platform.MacOS UpdateTextColor(); UpdateEditable(); UpdateMaxLength(); + UpdateIsReadOnly(); } protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) @@ -62,6 +63,8 @@ namespace Xamarin.Forms.Platform.MacOS UpdateFont(); else if (e.PropertyName == InputView.MaxLengthProperty.PropertyName) UpdateMaxLength(); + else if (e.PropertyName == Xamarin.Forms.InputView.IsReadOnlyProperty.PropertyName) + UpdateIsReadOnly(); } protected override void SetBackgroundColor(Color color) @@ -148,5 +151,12 @@ namespace Xamarin.Forms.Platform.MacOS if (currentControlText.Length > Element?.MaxLength) Control.StringValue = currentControlText.Substring(0, Element.MaxLength); } + + void UpdateIsReadOnly() + { + Control.Editable = !Element.IsReadOnly; + if (Element.IsReadOnly && Control.Window?.FirstResponder == Control.CurrentEditor) + Control.Window?.MakeFirstResponder(null); + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.MacOS/Renderers/EntryRenderer.cs b/Xamarin.Forms.Platform.MacOS/Renderers/EntryRenderer.cs index 0b3ab90..31e462c 100644 --- a/Xamarin.Forms.Platform.MacOS/Renderers/EntryRenderer.cs +++ b/Xamarin.Forms.Platform.MacOS/Renderers/EntryRenderer.cs @@ -132,6 +132,8 @@ namespace Xamarin.Forms.Platform.MacOS UpdateAlignment(); else if (e.PropertyName == InputView.MaxLengthProperty.PropertyName) UpdateMaxLength(); + else if (e.PropertyName == Xamarin.Forms.InputView.IsReadOnlyProperty.PropertyName) + UpdateIsReadOnly(); base.OnElementPropertyChanged(sender, e); } @@ -201,7 +203,8 @@ namespace Xamarin.Forms.Platform.MacOS UpdateFont(); UpdateAlignment(); UpdateMaxLength(); - } + UpdateIsReadOnly(); + } void TextFieldFocusChanged(object sender, BoolEventArgs e) { @@ -289,5 +292,13 @@ namespace Xamarin.Forms.Platform.MacOS if (currentControlText.Length > Element?.MaxLength) Control.StringValue = currentControlText.Substring(0, Element.MaxLength); } + + + void UpdateIsReadOnly() + { + Control.Editable = !Element.IsReadOnly; + if (Element.IsReadOnly && Control.Window?.FirstResponder == Control.CurrentEditor) + Control.Window?.MakeFirstResponder(null); + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.Tizen/Renderers/EditorRenderer.cs b/Xamarin.Forms.Platform.Tizen/Renderers/EditorRenderer.cs index 48b160c..dd57006 100644 --- a/Xamarin.Forms.Platform.Tizen/Renderers/EditorRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Renderers/EditorRenderer.cs @@ -16,6 +16,7 @@ namespace Xamarin.Forms.Platform.Tizen RegisterPropertyHandler(InputView.IsSpellCheckEnabledProperty, UpdateIsSpellCheckEnabled); RegisterPropertyHandler(Editor.PlaceholderProperty, UpdatePlaceholder); RegisterPropertyHandler(Editor.PlaceholderColorProperty, UpdatePlaceholderColor); + RegisterPropertyHandler(InputView.IsReadOnlyProperty, UpdateIsReadOnly); } protected override void OnElementChanged(ElementChangedEventArgs e) @@ -153,5 +154,10 @@ namespace Xamarin.Forms.Platform.Tizen return null; } + + void UpdateIsReadOnly() + { + Control.IsEditable = !Element.IsReadOnly; + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.Tizen/Renderers/EntryRenderer.cs b/Xamarin.Forms.Platform.Tizen/Renderers/EntryRenderer.cs index 715844e..ba77015 100644 --- a/Xamarin.Forms.Platform.Tizen/Renderers/EntryRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Renderers/EntryRenderer.cs @@ -23,6 +23,7 @@ namespace Xamarin.Forms.Platform.Tizen RegisterPropertyHandler(Entry.IsTextPredictionEnabledProperty, UpdateIsSpellCheckEnabled); RegisterPropertyHandler(Specific.FontWeightProperty, UpdateFontWeight); RegisterPropertyHandler(Entry.SelectionLengthProperty, UpdateSelectionLength); + RegisterPropertyHandler(InputView.IsReadOnlyProperty, UpdateIsReadOnly); } protected override void OnElementChanged(ElementChangedEventArgs e) @@ -198,5 +199,10 @@ namespace Xamarin.Forms.Platform.Tizen return Element.Text.IndexOf(selection, Math.Max(Control.CursorPosition - selection.Length, 0)); } + + void UpdateIsReadOnly() + { + Control.IsEditable = !Element.IsReadOnly; + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.UAP/EditorRenderer.cs b/Xamarin.Forms.Platform.UAP/EditorRenderer.cs index 188ae47..624c15a 100644 --- a/Xamarin.Forms.Platform.UAP/EditorRenderer.cs +++ b/Xamarin.Forms.Platform.UAP/EditorRenderer.cs @@ -62,6 +62,7 @@ namespace Xamarin.Forms.Platform.UWP UpdateDetectReadingOrderFromContent(); UpdatePlaceholderText(); UpdatePlaceholderColor(); + UpdateIsReadOnly(); } base.OnElementChanged(e); @@ -127,6 +128,8 @@ namespace Xamarin.Forms.Platform.UWP UpdatePlaceholderText(); else if (e.PropertyName == Editor.PlaceholderColorProperty.PropertyName) UpdatePlaceholderColor(); + else if (e.PropertyName == InputView.IsReadOnlyProperty.PropertyName) + UpdateIsReadOnly(); } void OnLostFocus(object sender, RoutedEventArgs e) @@ -357,5 +360,10 @@ namespace Xamarin.Forms.Platform.UWP } } } + + void UpdateIsReadOnly() + { + Control.IsReadOnly = Element.IsReadOnly; + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.UAP/EntryRenderer.cs b/Xamarin.Forms.Platform.UAP/EntryRenderer.cs index 8c37a37..27cbd46 100644 --- a/Xamarin.Forms.Platform.UAP/EntryRenderer.cs +++ b/Xamarin.Forms.Platform.UAP/EntryRenderer.cs @@ -61,6 +61,7 @@ namespace Xamarin.Forms.Platform.UWP UpdateMaxLength(); UpdateDetectReadingOrderFromContent(); UpdateReturnType(); + UpdateIsReadOnly(); UpdateInputScope(); if (_cursorPositionChangePending) @@ -136,6 +137,8 @@ namespace Xamarin.Forms.Platform.UWP UpdateCursorPosition(); else if (e.PropertyName == Entry.SelectionLengthProperty.PropertyName) UpdateSelectionLength(); + else if (e.PropertyName == InputView.IsReadOnlyProperty.PropertyName) + UpdateIsReadOnly(); } protected override void UpdateBackgroundColor() @@ -424,5 +427,10 @@ namespace Xamarin.Forms.Platform.UWP _nativeSelectionIsUpdating = false; } } + + void UpdateIsReadOnly() + { + Control.IsReadOnly = Element.IsReadOnly; + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.WPF/Renderers/EditorRenderer.cs b/Xamarin.Forms.Platform.WPF/Renderers/EditorRenderer.cs index 1b6d03b..cbaef0a 100644 --- a/Xamarin.Forms.Platform.WPF/Renderers/EditorRenderer.cs +++ b/Xamarin.Forms.Platform.WPF/Renderers/EditorRenderer.cs @@ -27,6 +27,7 @@ namespace Xamarin.Forms.Platform.WPF UpdateTextColor(); UpdateFont(); UpdateMaxLength(); + UpdateIsReadOnly(); } base.OnElementChanged(e); @@ -51,6 +52,8 @@ namespace Xamarin.Forms.Platform.WPF UpdateFont(); else if (e.PropertyName == InputView.MaxLengthProperty.PropertyName) UpdateMaxLength(); + else if (e.PropertyName == InputView.IsReadOnlyProperty.PropertyName) + UpdateIsReadOnly(); } void NativeOnTextChanged(object sender, System.Windows.Controls.TextChangedEventArgs textChangedEventArgs) @@ -138,5 +141,10 @@ namespace Xamarin.Forms.Platform.WPF _isDisposed = true; base.Dispose(disposing); } + + void UpdateIsReadOnly() + { + Control.IsReadOnly = Element.IsReadOnly; + } } } \ No newline at end of file diff --git a/Xamarin.Forms.Platform.WPF/Renderers/EntryRenderer.cs b/Xamarin.Forms.Platform.WPF/Renderers/EntryRenderer.cs index c78a431..321740d 100644 --- a/Xamarin.Forms.Platform.WPF/Renderers/EntryRenderer.cs +++ b/Xamarin.Forms.Platform.WPF/Renderers/EntryRenderer.cs @@ -35,6 +35,7 @@ namespace Xamarin.Forms.Platform.WPF UpdateAlignment(); UpdatePlaceholderColor(); UpdateMaxLength(); + UpdateIsReadOnly(); } base.OnElementChanged(e); @@ -66,6 +67,8 @@ namespace Xamarin.Forms.Platform.WPF UpdatePlaceholderColor(); else if (e.PropertyName == InputView.MaxLengthProperty.PropertyName) UpdateMaxLength(); + else if (e.PropertyName == InputView.IsReadOnlyProperty.PropertyName) + UpdateIsReadOnly(); } internal override void OnModelFocusChangeRequested(object sender, VisualElement.FocusRequestArgs args) @@ -259,5 +262,10 @@ namespace Xamarin.Forms.Platform.WPF _isDisposed = true; base.Dispose(disposing); } + + void UpdateIsReadOnly() + { + Control.IsReadOnly = Element.IsReadOnly; + } } } diff --git a/Xamarin.Forms.Platform.iOS/Renderers/EditorRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/EditorRenderer.cs index 4654329..47d0577 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/EditorRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/EditorRenderer.cs @@ -79,6 +79,8 @@ namespace Xamarin.Forms.Platform.iOS UpdateTextAlignment(); UpdateMaxLength(); UpdateAutoSizeOption(); + UpdateReadOnly(); + UpdateUserInteraction(); } private void UpdateAutoSizeOption() @@ -134,8 +136,8 @@ namespace Xamarin.Forms.Platform.iOS UpdateKeyboard(); else if (e.PropertyName == Editor.IsTextPredictionEnabledProperty.PropertyName) UpdateKeyboard(); - else if (e.PropertyName == VisualElement.IsEnabledProperty.PropertyName) - UpdateEditable(); + else if (e.PropertyName == VisualElement.IsEnabledProperty.PropertyName || e.PropertyName == Xamarin.Forms.InputView.IsReadOnlyProperty.PropertyName) + UpdateUserInteraction(); else if (e.PropertyName == Editor.TextColorProperty.PropertyName) UpdateTextColor(); else if (e.PropertyName == Editor.FontAttributesProperty.PropertyName) @@ -277,6 +279,19 @@ namespace Xamarin.Forms.Platform.iOS return newLength <= Element.MaxLength; } + void UpdateReadOnly() + { + Control.UserInteractionEnabled = !Element.IsReadOnly; + } + + void UpdateUserInteraction() + { + if (Element.IsEnabled && Element.IsReadOnly) + UpdateReadOnly(); + else + UpdateEditable(); + } + internal class FormsUITextView : UITextView { public event EventHandler ContentSizeChanged; diff --git a/Xamarin.Forms.Platform.iOS/Renderers/EntryRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/EntryRenderer.cs index 9db1f4c..e286eeb 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/EntryRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/EntryRenderer.cs @@ -126,6 +126,7 @@ namespace Xamarin.Forms.Platform.iOS UpdateCursorSelection(); UpdateCursorColor(); + UpdateIsReadOnly(); } protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) @@ -171,6 +172,8 @@ namespace Xamarin.Forms.Platform.iOS UpdateCursorSelection(); else if (e.PropertyName == Specifics.CursorColorProperty.PropertyName) UpdateCursorColor(); + else if (e.PropertyName == Xamarin.Forms.InputView.IsReadOnlyProperty.PropertyName) + UpdateIsReadOnly(); base.OnElementPropertyChanged(sender, e); } @@ -478,5 +481,10 @@ namespace Xamarin.Forms.Platform.iOS _nativeSelectionIsUpdating = false; } } - } + + void UpdateIsReadOnly() + { + Control.UserInteractionEnabled = !Element.IsReadOnly; + } + } } -- 2.7.4