unoplatform / uno

Open-source platform for building cross-platform native Mobile, Web, Desktop and Embedded apps quickly. Create rich, C#/XAML, single-codebase apps from any IDE. Hot Reload included! 90m+ NuGet Downloads!!
https://platform.uno
Apache License 2.0
8.84k stars 712 forks source link

[WASM][.NET 6] Custom themes not working properly #7722

Open DierkDroth opened 2 years ago

DierkDroth commented 2 years ago

Current behavior

I applied custom, compact theming to my WindowsAppSDK + .NET 6 app. This would not work as expected on UNO WASM

Expected behavior

WASM should work as WindowsAppSDK

How to reproduce it (as minimally and precisely as possible)

MyUnoApp.zip Please try attached WASM and WINUI heads and notice the difference

Workaround

None (AFAIK)

Works on UWP/WinUI

No response

Environment

No response

NuGet package version(s)

Latest

Affected platforms

WebAssembly

IDE

Visual Studio 2022

IDE version

No response

Relevant plugins

No response

Anything else we need to know?

No response

DierkDroth commented 2 years ago

I needed to understand how custom styling could be applied to UNO WASM projects. If the way above - which works for UWP/WinUI3/WindowsAppSDK - is not the suggested way, then I would appreciated any pointer on how I could get custom styling working in UNO WASM.

Thanks in advance

Xiaoy312 commented 2 years ago

I cant comment on why there are such discrepancies between uno/uwp, but I have found the necessary changes to achieve the desired results: image

WASM before ![image](https://user-images.githubusercontent.com/2359550/151714134-bb8093e5-d826-4b7f-99da-d06131a1dfcf.png)

For some control, TextBox & PasswordBox, it is just a matter of resetting the padding property:

    <!-- uncomment and/or adjust if needed to be
    <Style TargetType="Button">
        <Setter Property="Padding" Value="{StaticResource CustomThickness}" />
    </Style>
    -->
    <Style TargetType="TextBox">
        <Setter Property="Padding" Value="{StaticResource CustomThickness}" />
    </Style>
    <Style TargetType="PasswordBox">
        <Setter Property="Padding" Value="{StaticResource CustomThickness}" />
    </Style>

For other controls, ListView + RadioButton + ToggleSwitch, its control-template needs to be modified: // you can pin-point the changes by searching (ctrl+f) for "void"

ListViewItem ```xml ```
RadioButton ```xml ```
ToggleSwitch ```xml ```
Xiaoy312 commented 2 years ago

The updated solution can be found here: 7722Repro.zip

As for how to troubleshoot these problems, you can use the XyVTH.TreeGraph(CONTROL_TO_DEBUG, DebugVTNode) to print the visual tree along with properties that you deem pertinent: // XyVTH.TreeGraph implementation can be found from the updated source above

        static string DebugVTNode(DependencyObject x)
        {
            var xname = (x as FrameworkElement)?.Name;
            var details = x switch
            {
                //RadioButton radio => $"{DescribeVisibilityEx(radio)}, enabled={radio.IsEnabled}, checked={radio.IsChecked}, {DescribeBrush(radio.Foreground, "foreground")}, {DescribeBrush(radio.Background, "background")}, {DescribeBrush(radio.BorderBrush, "borderbrush")}",
                //Grid grid => $"{DescribeVisibilityEx(grid)}, {DescribeBrush(grid.Background, "background")}",
                //Ellipse ellipse => $"{DescribeVisibilityEx(ellipse)}, {DescribeBrush(ellipse.Fill, "fill")}, {DescribeBrush(ellipse.Stroke, "stroke")}*{ellipse.StrokeThickness}px",

                //ContentPresenter, ImplicitTextBlock => dont care,
                _ => default(string),
            };

            return new StringBuilder()
                .Append(x.GetType().Name)
                //.Append($"#{x.GetHashCode():X8}")
                .AppendIf(!string.IsNullOrEmpty(xname), $"@{xname}")
                .Append("\\ ")
                .AppendIfTyped<FrameworkElement>(x, y => y.Style != null ? "Styled, " : "")
                .AppendIfTyped<FrameworkElement>(x, y => y.MinHeight > 0, y => $"MinHeight={y.MinHeight}, ")
                .AppendIfTyped<Shape>(x, y => y.MinHeight > 0, y => $"MinHeight={y.MinHeight}, ")

                .AppendIfTyped<FrameworkElement>(x, y => $"Actual={y.ActualWidth}x{y.ActualHeight}, Margin={y.Margin}, ")
                .AppendIfTyped<Grid>(x, y => $"Padding={y.Padding}, ")
                .AppendIfTyped<Border>(x, y => $"Padding={y.Padding}, ")
                .AppendIfTyped<Control>(x, y => $"Padding={y.Padding}, ")
                .AppendIfTyped<ContentPresenter>(x, y => $"Padding={y.Padding}, ")
                .AppendIfTyped<TextBlock>(x, y => $"Padding={y.Padding}, ")

                .ToString();
        }

It generates something like:

ToggleSwitch\ Actual=154x20, Margin=[Thickness: 0-0-0-0], Padding=[Thickness: 0-0-0-0], 
    Grid\ Actual=154x20, Margin=[Thickness: 0-0-0-0], Padding=[Thickness: 0-0-0-0], 
        ElementStub@HeaderContentPresenter\ Actual=0x0, Margin=[Thickness: 0-0-0-0], 
        ContentPresenter@OffContentPresenter\ Actual=22x20, Margin=[Thickness: 0-0-0-0], Padding=[Thickness: 0-0-0-0], 
            ImplicitTextBlock\ Actual=22x20, Margin=[Thickness: 0-0-0-0], Padding=[Thickness: 0-0-0-0], 
        ContentPresenter@OnContentPresenter\ Actual=21x20, Margin=[Thickness: 0-0-0-0], Padding=[Thickness: 0-0-0-0], 
            ImplicitTextBlock\ Actual=21x20, Margin=[Thickness: 0-0-0-0], Padding=[Thickness: 0-0-0-0], 
        Grid\ Actual=78x10, Margin=[Thickness: 0-5-0-5], Padding=[Thickness: 0-0-0-0], 
        Rectangle@OuterBorder\ Actual=44x20, Margin=[Thickness: 0-0-0-0], 
            SvgElement\ 
        Rectangle@SwitchKnobBounds\ Actual=44x20, Margin=[Thickness: 0-0-0-0], 
            SvgElement\ 
        Grid@SwitchKnob\ Actual=20x20, Margin=[Thickness: 0-0-0-0], Padding=[Thickness: 0-0-0-0], 
            Ellipse@SwitchKnobOn\ Actual=10x10, Margin=[Thickness: 0-0-0-0], 
                SvgElement\ 
            Ellipse@SwitchKnobOff\ Actual=10x10, Margin=[Thickness: 0-0-0-0], 
                SvgElement\ 
        Thumb@SwitchThumb\ Actual=78x20, Margin=[Thickness: 0-0-0-0], Padding=[Thickness: 0-0-0-0], 
            Rectangle\ Actual=78x20, Margin=[Thickness: 0-0-0-0], 
                SvgElement\ 

which you can use to pinpoint where exactly it went wrong, and then compare with the default style defined in generic.xaml(uno) to figure out what to do.

DierkDroth commented 2 years ago

Wow, thanks for your feedback on for your hard work on the subject! Much appreciated

Xiaoy312 commented 2 years ago

reopening this to investigate the discrepancies between uwp/uno on styles

agneszitte commented 1 year ago

@kazo0 / @Xiaoy312 Do you have an idea of the status of this issue please?

Xiaoy312 commented 1 year ago

Currently there is no plan to work on this.

What needs to be done is to go through each control styles to identify why the difference existing, and make correction if warranted warranted. Since, I think, the styles were almost 1:1 replica of windows baring a few not-yet-supported features, there is no reason why they won't look and measure exactly the same.

DierkDroth commented 1 year ago

@Xiaoy312 I agree: I don't think there is something wrong with the 1:1 replicas.

However, I believe there is a general 'lack of understanding' (no offense) on what actually might cause the scaling difference. My - uneducated - guess is that there is something boiling under the hood causing 'everything' to scale up (or down). I even would speculate that the root cause could be something related to different sizes of the 'logical pixels'.