Styling and theming

You can style components or widgets directly in C#, for example creating a library of reusable custom widgets as classes or functions. The below code uses a static function to return a customized button:

public static RxButton PrimaryButton(string text)
    => new RxButton(text)
        .BackgroundColor(ThemeColor.CommunicationCommunicationPrimary)
        .TextColor(ThemeColor.NeutralWhite)
        .BorderWidth(0)
        .CornerRadius(2)
        .Padding(5, 0);

NOTE: Styling thru XAML (Resources) is not currently supported

Theming

Another powerful way to style an entire page is using an RxTheme object. A theme provides an efficient way to style every control present in a page. For example consider we want to style an application with a Dark and Light theme, we could create 2 RxTheme:

public static class Theme
{
    public static RxTheme Light()
        => new RxTheme()
            .StyleFor<RxLabel>(_ =>
            {
                _.TextColor(Color.Black);
                _.Margin(0, 10);
            })
            .StyleFor<RxEntry>(_ =>
            {
                _.TextColor(Color.Black);
                _.Margin(0, 10);
                _.BackgroundColor(Color.White);
            })
            .StyleFor<RxButton>(_ =>
            {
                _.TextColor(Color.Black);
                _.Margin(10);
                _.BackgroundColor(Color.DarkGray);
            })
            .StyleFor<RxNavigationPage>(_ =>
            {
                _.BarBackgroundColor((Color)NavigationPage.BarBackgroundColorProperty.DefaultValue);
                _.BarTextColor((Color)NavigationPage.BarTextColorProperty.DefaultValue);
            })
            .StyleFor<RxContentPage>(_ =>
            {
                _.BackgroundColor((Color)ContentPage.BackgroundColorProperty.DefaultValue);
                _.Padding(10);
            });

    public static RxTheme Dark()
        => new RxTheme()
            .StyleFor<RxLabel>(_ =>
            {
                _.TextColor(Color.White);
                _.Margin(0, 10);
            })
            .StyleFor<RxEntry>(_ =>
            {
                _.TextColor(Color.Black);
                _.Margin(0, 10);
                _.BackgroundColor(Color.LightGray);
            })
            .StyleFor<RxButton>(_ =>
            {
                _.TextColor(Color.Black);
                _.Margin(10);
                _.BackgroundColor(Color.LightGray);
            })
            .StyleFor<RxNavigationPage>(_ =>
            {
                _.BarBackgroundColor(Color.DarkGray);
                _.BarTextColor(Color.White);
            })
            .StyleFor<RxContentPage>(_ =>
            {
                _.BackgroundColor(Color.Black);
                _.Padding(10);
            });
}

Now we can wrap any component/visual with these themes to automatically change its style:

public enum ThemeColor
{ 
    Dark,

    Light
}

public class MainPageState : IState
{
    public ThemeColor ThemeColor { get; set; } = ThemeColor.Light;
}

public class MainPage : RxComponent<MainPageState>
{
    public override VisualNode Render()
    {
        return new RxNavigationPage()
        {
            new RxContentPage()
            { 
                new RxStackLayout()
                { 
                    new RxLabel("Label"),
                    new RxEntry(),
                    new RxButton("Toggle Theme")
                        .OnClick(()=> SetState(s => s.ThemeColor = (s.ThemeColor == ThemeColor.Dark ? ThemeColor.Light : ThemeColor.Dark)))
                }
            }
            .Title("Theming")
        }
        .UseTheme(State.ThemeColor == ThemeColor.Dark ? Theme.Dark() : Theme.Light());
    }
}

This should be the final effect:

Dynamically change page theme

Last updated

Was this helpful?