Xamarin Forms UWP - Entry Typing Color

Emixam23Emixam23 ✭✭✭USMember ✭✭✭

Hi,

I have this CustomEntry in the PCL part:

public class CustomEntry : Entry
{
    /// <summary>
    /// The HasBorder property.
    /// </summary>
    public static readonly BindableProperty HasBorderProperty =
        BindableProperty.Create(nameof(HasBorder), typeof(bool), typeof(CustomEntry), true);

    /// <summary>
    /// Assessor for the HasBorder property.
    /// </summary>
    public bool HasBorder
    {
        get { return (bool)GetValue(HasBorderProperty); }
        set { SetValue(HasBorderProperty, value); }
    }

    /// <summary>
    /// The XAlign property
    /// </summary>
    public static readonly BindableProperty XAlignProperty =
        BindableProperty.Create("XAlign", typeof(TextAlignment), typeof(CustomEntry),
        TextAlignment.Start);

    /// <summary>
    /// Gets or sets the X alignment of the text
    /// </summary>
    public TextAlignment XAlign
    {
        get { return (TextAlignment)GetValue(XAlignProperty); }
        set { SetValue(XAlignProperty, value); }
    }
}

Then a renderer for the UWP part:

public class CustomEntryRenderer : EntryRenderer
{
    /// <summary>
    /// Instance of our Custom control declared in the PCL part.
    /// </summary>
    CustomEntry customEntry;

    /// <summary>
    /// We override the OnElementChanged() event handler to get the desired instance. We also use it for updates.
    /// </summary>
    /// <param name="e">It contains either the NewElement or the OldElement.</param>
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);

        if (e.NewElement != null)
        {
            customEntry = e.NewElement as CustomEntry;

            if (customEntry != null)
            {
                SetTextAlignment();
                SetBorderPresence();
                SetTextColor();
            }
        }
    }


    /// <summary>
    /// The on element property changed callback.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="PropertyChangedEventArgs"/>Instance containing the event data.</param>
    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName == CustomEntry.XAlignProperty.PropertyName)
            SetTextAlignment();
        else if (e.PropertyName == CustomEntry.HasBorderProperty.PropertyName)
            SetBorderPresence();
        else if (e.PropertyName == CustomEntry.TextColorProperty.PropertyName)
            SetTextColor();
    }

    /// <summary>
    /// Sets the text alignment.
    /// </summary>
    /// <param name="view">The view.</param>
    private void SetTextAlignment()
    {
        switch (customEntry.XAlign)
        {
            case Xamarin.Forms.TextAlignment.Center:
                Control.TextAlignment = Windows.UI.Xaml.TextAlignment.Center;
                break;
            case Xamarin.Forms.TextAlignment.End:
                Control.TextAlignment = Windows.UI.Xaml.TextAlignment.Right;
                break;
            case Xamarin.Forms.TextAlignment.Start:
                Control.TextAlignment = Windows.UI.Xaml.TextAlignment.Left;
                break;
        }
    }

    /// <summary>
    /// Sets the border presence.
    /// </summary>
    private void SetBorderPresence()
    {
        if (!customEntry.HasBorder)
        {
            Control.BorderThickness = new Windows.UI.Xaml.Thickness();
        }
    }

    /// <summary>
    /// Set the Text color.
    /// </summary>
    private void SetTextColor()
    {
        /*Control.ForegroundFocusBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(255,
            Convert.ToByte(customEntry.TextColor.R),
            Convert.ToByte(customEntry.TextColor.G),
            Convert.ToByte(customEntry.TextColor.B)));

        Brush tmp = (SolidColorBrush)new ColorConverter().Convert(customEntry.TextColor, null, null, null);

        Control.ForegroundFocusBrush = (SolidColorBrush)new ColorConverter().Convert(customEntry.TextColor, null, null, null);
        Debug.WriteLine("Pass");*/
    }
}

The thing is, when I'm typing, the textColor is black, means I don't think what I'm typing because it's black over dark design.. Does someone know how to change the color of typing? Because when I unfocus de Entry, the Text becomes White, like I want so..

There is the XAML declaration:

        <AbsoluteLayout WidthRequest="{Binding EntryWidth}" HeightRequest="{Binding EntryHeight}">
          <control:CustomEntry Placeholder="pseudo" PlaceholderColor="Gray"
                               Text="" FontFamily="{extension:FontFamily Roboto_Light}" FontSize="20" TextColor="White"
                               XAlign="Center" HasBorder="false" BackgroundColor="Transparent"
                               AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                               AbsoluteLayout.LayoutFlags="All"/>
          <BoxView BackgroundColor="{StaticResource NL_OrangeBeer}"
                   AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 0.02"
                   AbsoluteLayout.LayoutFlags="All"/>
        </AbsoluteLayout>

Thank in advance !

Tagged:

Best Answers

  • JohnHardmanJohnHardman mod GB mod
    Accepted Answer

    @Emixam23 - There isn't anything more to it than that - in 2.3.2.127, you change the default color used for the focus text of an Entry, by adding a setter for the FormsTextBoxStyle, using those two lines (with the value specified here, the text will be green):

    Windows.UI.Xaml.Style style = Windows.UI.Xaml.Application.Current.Resources["FormsTextBoxStyle"] as Windows.UI.Xaml.Style;
    style.Setters.Add(new Windows.UI.Xaml.Setter { Property = FormsTextBox.ForegroundFocusBrushProperty, Value = Color.FromArgb(255, 0, 255, 0) });

    I'm done for today, but if you're still having trouble with it, I'll see what I can do tomorrow.

Answers

  • C_BarbourC_Barbour ✭✭ USUniversity ✭✭

    Hi,

    From what I can tell, it looks like you've been trying to access the right variable but your colorConverter might be off so it's defaulting to black?

    Control.ForegroundFocusBrush = new SolidColorBrush(Windows.UI.Colors.White);

    If you want to change the color when it's not focused it would just be:

    Control.Foreground = new SolidColorBrush(Windows.UI.Colors.White);

    Hope this helps.

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    Doesn't work :/ still black entry :(

    But it's weird, because when I unfocus it, it turns to White.. And if no text is in, then the PlaceHolder is Gray, so like I want.. Just at the moment of typing, the text is black

  • C_BarbourC_Barbour ✭✭ USUniversity ✭✭

    Have you tried just putting in the code above as such:

    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
    base.OnElementChanged(e);

    if (Control == null) return;
    
    Control.ForegroundFocusBrush = new SolidColorBrush(Windows.UI.Colors.White);
    Control.Foreground = new SolidColorBrush(Windows.UI.Colors.White);
    

    }

    Control.PlaceholderForegroundBrush is a different brush again if you wanted it to be white as well you'd add it as above.

    Have you tried hard-coding the colors instead of using your BindingProperty's?

    I spent a silly amount of time testing these brushes so I feel your pain.

  • C_BarbourC_Barbour ✭✭ USUniversity ✭✭

    @JohnHardman Thanks John, this might come in handy for a lot of other things I'm working on!

  • JohnHardmanJohnHardman mod GBUniversity mod
    edited October 2016

    @C_Barbour - As far as I know, most of those bits are undocumented. It takes a bit of reverse engineering of the XF source code to work out which styles, brushes etc to use.

    I cannot make any guarantees for the few below, but these are ones I have in my code with comments that may or may not still be accurate :-) The list of resource keys is significantly longer though - I went through the XF source some time back and built a list that I think was complete at that time, although without working out what they all do/did.

                // This is used as the background color on action sheets and dropdown menus.
                // This will also be used as the background color of the navigation bar if
                // navigationPage.BarBackgroundColor is set to Color.Default
                Windows.UI.Xaml.Application.Current.Resources["SystemControlBackgroundChromeMediumLowBrush"] =
                    new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
    
                // This is used as the text color for text and images on the navigation bar
                Windows.UI.Xaml.Application.Current.Resources["ApplicationForegroundThemeBrush"] =
                    new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
    
                // On UWP, this one is used to paint the color of button borders when they lose focus
                Windows.UI.Xaml.Application.Current.Resources["ButtonBorderThemeBrush"] =
                    new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
    
                // This is used as the text color for text in ListViews
                Windows.UI.Xaml.Application.Current.Resources["DefaultTextForegroundThemeBrush"] =
                    new SolidColorBrush(Color.FromArgb(255, 0, 255, 0));
    
                // On UWP, this one is used to set the text color in Entry fields when they have the focus
                Windows.UI.Xaml.Style style = Windows.UI.Xaml.Application.Current.Resources["FormsTextBoxStyle"] as Windows.UI.Xaml.Style;
                style.Setters.Add(new Windows.UI.Xaml.Setter { Property = FormsTextBox.ForegroundFocusBrushProperty, Value = Color.FromArgb(255, 0, 255, 0) });
    
  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    Hi guys,

    I searched so much and then, after a long time, I finally have answers and these seems really interesting. I red it from my phone but Ill try from my computer later in the day and let you know !

    Thank again

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭
    edited October 2016

    Where do you put this code? beucase it doesn't work :/ @JohnHardman

  • JohnHardmanJohnHardman mod GBUniversity mod
    edited October 2016

    @Emixam23 - It goes after the call to Forms.Init in the App,xaml.cs file of your UWP project.

    The attached screenshot shows a test page with an Entry using this value indicated by a red arrow. Definitely works :-)

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    I put in MainPage.xaml.cs .. I'll try in 2min thank !

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    I don't have any Forms.Init() in the UWP part, either in the MainPage.xaml.cs or App.xaml.cs

  • JohnHardmanJohnHardman mod GBUniversity mod
    edited October 2016

    @Emixam23 - Actually, thinking about it, it doesn't have to be after Forms.Init - put it in the App.OnLaunched method for your UWP project.

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭
    edited October 2016

    Doesn't work.. Maybe I don't put the code at the right position

        /// <summary>
        /// Invoked when the application is launched normally by the end user.  Other entry points
        /// will be used such as when the application is launched to open a specific file.
        /// </summary>
        /// <param name="e">Details about the launch request and process.</param>
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {
    
    #if DEBUG
            if (System.Diagnostics.Debugger.IsAttached)
            {
                this.DebugSettings.EnableFrameRateCounter = true;
            }
    #endif
    
            Frame rootFrame = Window.Current.Content as Frame;
    
            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active
            if (rootFrame == null)
            {
                // Create a Frame to act as the navigation context and navigate to the first page
                rootFrame = new Frame();
    
                rootFrame.NavigationFailed += OnNavigationFailed;
    
                Xamarin.Forms.Forms.Init(e);
    
                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    //TODO: Load state from previously suspended application
                }
    
                // Place the frame in the current Window
                Window.Current.Content = rootFrame;
            }
    
            if (rootFrame.Content == null)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                rootFrame.Navigate(typeof(MainPage), e.Arguments);
            }
            // Ensure the current window is active
            Window.Current.Activate();
    
            // On UWP, this one is used to set the text color in Entry fields when they have the focus
            Windows.UI.Xaml.Style style = Windows.UI.Xaml.Application.Current.Resources["FormsTextBoxStyle"] as Windows.UI.Xaml.Style;
            style.Setters.Add(new Windows.UI.Xaml.Setter { Property = FormsTextBox.ForegroundFocusBrushProperty, Value = Color.FromArgb(255, 0, 255, 0) });
        }
    
  • JohnHardmanJohnHardman mod GBUniversity mod

    @Emixam23 - I doubt it would make a difference, but I have those lines before the "if (rootFrame.Content == null)" line.

    Are you sure you haven't got code left over from investigation that might be preventing that the style info from being used? For example, in your current CustomEntryRenderer, CustomEntry, or in any style-related C# or XAML?

    Add a new Entry (not Custom Entry) to a page and see if that picks up the value from the style setter.

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    When the lines are here, it doesn't compile :/

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    What the hell, I did what you say but it's still black at the input moment, the things is, however, I add an entry, a normal one and, the input is still black..

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    Can you send me your solution please?

  • JohnHardmanJohnHardman mod GBUniversity mod
    Accepted Answer

    @Emixam23 - There isn't anything more to it than that - in 2.3.2.127, you change the default color used for the focus text of an Entry, by adding a setter for the FormsTextBoxStyle, using those two lines (with the value specified here, the text will be green):

    Windows.UI.Xaml.Style style = Windows.UI.Xaml.Application.Current.Resources["FormsTextBoxStyle"] as Windows.UI.Xaml.Style;
    style.Setters.Add(new Windows.UI.Xaml.Setter { Property = FormsTextBox.ForegroundFocusBrushProperty, Value = Color.FromArgb(255, 0, 255, 0) });

    I'm done for today, but if you're still having trouble with it, I'll see what I can do tomorrow.

  • JohnHardmanJohnHardman mod GBUniversity mod

    @Emixam23 - BTW - what version of XF are you building against?

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    I didnt check the version... Good point Ill let you know ;)

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    Thank for your help as well, that is really nice

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    Man, I don't have enough of word to say thank you so much, it was about the update ! And also your code, thank you again man ! :)

  • JohnHardmanJohnHardman mod GBUniversity mod

    @Emixam23 @C_Barbour - Just to complicate things - there appears to be a bug in XF for UWP, where if you use a Behavior to change the TextColor of an Entry, it doesn't take effect immediately as it does on Android and iOS. This is the case, whether or not you have used the FormsTextBoxStyle. Even updating the style itself does not work in this scenario.

    After spending a couple of hours investigating this, I discovered that it has already been logged as a confirmed bug, at https://bugzilla.xamarin.com/show_bug.cgi?id=41054

  • C_BarbourC_Barbour ✭✭ USUniversity ✭✭

    @JohnHardman Good to keep in mind, thanks for the update. Will not attempt :wink:

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    Really good to know, thank :)

  • JohnHardmanJohnHardman mod GBUniversity mod

    After a few more hours of trying different workarounds, nothing that I would present to an end user, so will be chasing up the bug to see if it can be fixed quickly :-(

  • MercifulGiraffeMercifulGiraffe ✭✭ USMember ✭✭

    So, the soluction from JohnHardman seems to set the colours for UWP on a global basis. what about if you want to have different text colours on different controls? I.e. red text in some input boxes and black in others?

  • Emixam23Emixam23 ✭✭✭ USMember ✭✭✭

    Good question.. I don't know, I didn't try because, just this solution, set every entry as the same color, it took me more than 1month.. of searches.. if you find something let me know please, a bug as been sent to bigzilla but still not answers about it :/

Sign In or Register to comment.