Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use style in BlazorBindings #119

Closed
shugaoye opened this issue Apr 28, 2023 · 11 comments
Closed

How to use style in BlazorBindings #119

shugaoye opened this issue Apr 28, 2023 · 11 comments
Labels
documentation Improvements or additions to documentation question Further information is requested

Comments

@shugaoye
Copy link

shugaoye commented Apr 28, 2023

I cannot find an example about CSS style. Can you provide an example to use CSS style?
Is it possible to use XAML style in Resources/Styles/Styles.xaml? If not, how can we translate it to CSS?

If I add a css like below, I got an exception.

<StyleSheet Resource="mystyle.css" Assembly="GetType().Assembly"></StyleSheet>
<TabbedPage>

    <ContentPage Title="Todo">
        <StackLayout>
            <Label FontSize="20" TextColor="Colors.Crimson" Text="Todo Items" HorizontalTextAlignment="TextAlignment.Center" />
            <TodoList />
        </StackLayout>
    </ContentPage>

    <ContentPage Title="Counter">
        <Counter />
    </ContentPage>

    <ContentPage Title="About">
        <About />
    </ContentPage>

</TabbedPage>

It cannot work and I found this exception.

System.ArgumentException: 'parentElement (Parameter 'Expected parent to be of type 'Microsoft.Maui.Controls.VisualElement' but it is of type 'BlazorBindings.Maui.BlazorBindingsApplication`1[[BlazorBindingsToDo.TodoApp, BlazorBindingsToDo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'.')'
@Dreamescaper
Copy link
Owner

I haven't added anything to have a better experience with XAML styles yet, but you can use those.
You can add something like that to your App constructor (if you're looking to apply them globally):

public class App : BlazorBindingsApplication<AppShell>
{
    public App(IServiceProvider services) : base(services)
    {
        var stylesType = typeof(App).Assembly.GetCustomAttributes<XamlResourceIdAttribute>()
            .First(a => a.Path == "Resources/Styles/Styles.xaml")
            .Type;

        var stylesResources = (ResourceDictionary)Activator.CreateInstance(stylesType);

        Resources.Add(stylesResources);
    }
}

@Dreamescaper
Copy link
Owner

If you want, you can define such styles with C# instead of XAML (although it looks a bit ugly to my taste). Here's the example:

    public static class Styles
    {
        public static void ApplyTo(ResourceDictionary dictionary)
        {
            dictionary.Add(_pageTitleLabelStyle);
            dictionary.Add(_stackLayoutSpacingStyle);
        }

        static readonly Style _stackLayoutSpacingStyle = new(typeof(StackBase))
        {
            Setters =
            {
                new(){ Property = StackBase.SpacingProperty, Value = 6 }
            },
            ApplyToDerivedTypes = true
        };

        static readonly Style _pageTitleLabelStyle = new(typeof(Label))
        {
            Class = "pageTitle",
            Setters =
            {
                new (){ Property = Label.HorizontalOptionsProperty, Value = LayoutOptions.Center },
                new (){ Property = Label.FontSizeProperty, Value = 30 },
                new (){ Property = Label.TextColorProperty, Value = Colors.Black },
                new (){ Property = Label.FontAttributesProperty, Value = FontAttributes.Bold },
            }
        };
    }

And in order to apply it to your app, add this to App constructor:

public class App : BlazorBindingsApplication<AppShell>
{
    public App(IServiceProvider services) : base(services)
    {
		Styles.ApplyTo(Resources);
    }
}

@Dreamescaper
Copy link
Owner

Dreamescaper commented Apr 29, 2023

As for CSS styles, StyleSheet razor component is made to allow applying CSS styles to separate elements (pages, etc) - that's why it is expected that this element is added as a child to the element you want to apply it to.

If you want to apply it globally, you probably don't need to use it in razor files at all, just add something like that to your App constructor:

using BlazorBindings.Maui;
using Microsoft.Maui.Controls.StyleSheets;

public class App : BlazorBindingsApplication<AppShell>
{
    public App(IServiceProvider services) : base(services)
    {
        Resources.Add(StyleSheet.FromResource("Resources/Styles/styles.css", GetType().Assembly));
    }
}

@Dreamescaper
Copy link
Owner

But you certainly right that I should add a sample for styling...

@CeSun
Copy link

CeSun commented May 3, 2023

But you certainly right that I should add a sample for styling...

I also agree with the proposal of this issue, every time I try blazorbindings again, I need to check how to introduce the resource of the third-party component。

   class App : BlazorBindingsApplication<AppShell>
    {
        public App(IServiceProvider services) : base(services)
        {
            Resources.Add(new MaterialStyles());
        }
    }

image

@Dreamescaper
Copy link
Owner

Dreamescaper commented May 3, 2023

I'm wondering whether there's anything related in MAUI's documentation regarding that.
Because this staff is not razor-specific, that's what you would do in regular MAUI if you don't want to use XAML.

Actually, the opposite is probably true as well, I think it is possible to define App with XAML for use with BlazorBindings, and include the resources there. Which kinda defeats the purpose, but anyway...

@Dreamescaper Dreamescaper added documentation Improvements or additions to documentation question Further information is requested labels May 3, 2023
@shugaoye
Copy link
Author

shugaoye commented May 6, 2023

I tested to add styles at App level per your suggestion and it works fine for me. Is there a way to add style at page or component level? Is it possible to support blazor css isolation? If you add a sample, that will be great.

@Dreamescaper
Copy link
Owner

Style property wasn't added to razor bindings, as there is no good way to define Style with Razor syntax. However, it should probably be added at least to support externally defined Styles.

But you can define your styles globally, and apply them based on StyleClasses:
https://learn.microsoft.com/en-us/dotnet/maui/user-interface/styles/xaml#style-classes

Alternatively, you can use CSS styles - you can apply them via that StyleSheet component you've mentioned before (e.g. add it as a child for your ContentPage).

I'll work on that to make styling a bit easier in the next release.

@Vinny636
Copy link

Vinny636 commented Jan 22, 2024

I wanted to add something to this discussion. I'm using .NET 8 with the nightly builds (BlazorBindings.Maui.Templates 2.0.8 and BlazorBindings.Maui 2.0.1) and I couldn't get CSS styling to work. It kept telling me that it couldn't find the stylesheet resource.

I finally figured out that you have to make the build action on the stylesheet "MauiCss", then it worked fine.

Here's the code in my App.cs, as an example:

using BlazorBindings.Maui;
using Microsoft.Maui.Controls.StyleSheets;

namespace BlazorBindingsTest
{
    public class App : BlazorBindingsApplication<MainPage>
    {
        public App(IServiceProvider services) : base(services)
        {
            Resources.Add(StyleSheet.FromResource("Resources/Styles/styles.css", GetType().Assembly));
        }
    }
}

Here is the build action on my stylesheet:

Screenshot from Visual Studio 2022

@Dreamescaper
Copy link
Owner

Sorry for the delay, I need to have a bit of rest, but I'll try to get to it as soon as I can.

@Dreamescaper
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants