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 !
@Emixam23 @CarolynBarbour - In 2.3.2.127, the Entry colors seem to behave sensibly as long as you override all color properties.
If you want to change the defaults, you can utilise "FormsTextBoxStyle" to change the text color for when the Entry has focus. I did the following in the App.xaml.cs in my UWP project:
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) });
@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.
@Emixam23 - Here you go. This is a newly created app, using two NuGet packages:
(1) Microsoft.NETCore.UniversalWindowsPlatform v5.2.2
(2) Xamarin.Forms v2.3.2.127
First the App.xaml.cs from the UWP project
using System; using Windows.ApplicationModel; using Windows.ApplicationModel.Activation; using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; using Xamarin.Forms.Platform.UWP; namespace App7.UWP { /// <summary> /// Provides application-specific behavior to supplement the default Application class. /// </summary> sealed partial class App : Application { /// <summary> /// Initializes the singleton application object. This is the first line of authored code /// executed, and as such is the logical equivalent of main() or WinMain(). /// </summary> public App() { this.InitializeComponent(); this.Suspending += OnSuspending; } /// <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; } 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) }); 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(); } /// <summary> /// Invoked when Navigation to a certain page fails /// </summary> /// <param name="sender">The Frame which failed navigation</param> /// <param name="e">Details about the navigation failure</param> void OnNavigationFailed(object sender, NavigationFailedEventArgs e) { throw new Exception("Failed to load Page " + e.SourcePageType.FullName); } /// <summary> /// Invoked when application execution is being suspended. Application state is saved /// without knowing whether the application will be terminated or resumed with the contents /// of memory still intact. /// </summary> /// <param name="sender">The source of the suspend request.</param> /// <param name="e">Details about the suspend request.</param> private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); //TODO: Save application state and stop any background activity deferral.Complete(); } } }
And then the App.cs from the Portable project:
using Xamarin.Forms; namespace App7 { public class App : Application { public App() { // The root page of your application MainPage = new ContentPage { Content = new StackLayout { VerticalOptions = LayoutOptions.Center, Children = { new Entry { HorizontalOptions = LayoutOptions.FillAndExpand, Placeholder = "Enter text here" } } } }; } protected override void OnStart() { // Handle when your app starts } protected override void OnSleep() { // Handle when your app sleeps } protected override void OnResume() { // Handle when your app resumes } } }
This will give you green text when you type into the Entry.
Answers
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.
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
Have you tried just putting in the code above as such:
protected override void OnElementChanged(ElementChangedEventArgs e)
{
base.OnElementChanged(e);
}
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.
@Emixam23 @CarolynBarbour - In 2.3.2.127, the Entry colors seem to behave sensibly as long as you override all color properties.
If you want to change the defaults, you can utilise "FormsTextBoxStyle" to change the text color for when the Entry has focus. I did the following in the App.xaml.cs in my UWP project:
@JohnHardman Thanks John, this might come in handy for a lot of other things I'm working on!
@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.
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
Where do you put this code? beucase it doesn't work
@JohnHardman
@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 :-)
I put in MainPage.xaml.cs .. I'll try in 2min thank !
I don't have any Forms.Init() in the UWP part, either in the MainPage.xaml.cs or App.xaml.cs
@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.
Doesn't work.. Maybe I don't put the code at the right position
@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.
When the lines are here, it doesn't compile
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..
Can you send me your solution please?
@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.
@Emixam23 - BTW - what version of XF are you building against?
I didnt check the version... Good point Ill let you know
Thank for your help as well, that is really nice
@Emixam23 - Here you go. This is a newly created app, using two NuGet packages:
(1) Microsoft.NETCore.UniversalWindowsPlatform v5.2.2
(2) Xamarin.Forms v2.3.2.127
First the App.xaml.cs from the UWP project
And then the App.cs from the Portable project:
This will give you green text when you type into the Entry.
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 !
@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
@JohnHardman Good to keep in mind, thanks for the update. Will not attempt
Really good to know, thank
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 :-(
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?
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