I have a simple, un-themed Maui app. Maui's default colour binding works as expected when I change the Windows theme between dark and light, which is what I want.
I have a Border
object that is part of a Grid
layout and which is positioned over some other elements. For visual design reasons I want the other elements to be partly visible through it, so I set its Opacity
to 0.75. I don't specify its background colour because I want it to use the default for the current system theme. This worked until recently, but now the opacity only seems to be applied if a background colour is also explicitly specified - which I don't want to do for the reason described above. Is there a way to have a partly-opaque Border
without hard-coding a background colour?
The following xaml is a cut-down example:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage">
<Grid>
<VerticalStackLayout
Grid.Row="0" Grid.Column="0">
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
</VerticalStackLayout>
<Border
Opacity="0.75"
Grid.Row="0" Grid.Column="0" ZIndex="99"
HorizontalOptions="Start" VerticalOptions="Start"
WidthRequest="200" HeightRequest="100"
Stroke="white" StrokeThickness="3"/>
</Grid>
</ContentPage>
Running this gives me the following result where the Label
elements are not opaqued by the Border
:
If I change the Border
element's xaml to include, for example, BackgroundColor="LightGreen"
then I get the following result, where the Label
elements are opaqued by the Border
:
I do want the opaqueness but I don't want to hard-code a background colour - I want Maui to choose the appropriate one depending on the system theme. How can I achieve this? Do I have to theme the app and tightly specify element colours?
(I'm targeting Windows and Mac only using .net 6 in current VS2022 mainline on Win11.)
CodePudding user response:
Since you need a background color that an opacity can be applied to, you're required to set one, otherwise you'll be setting the opacity for a transparent background, which is pointless.
In order to achieve your goal of covering some content using a Border
, you could just set the same color to your Border
's background as the background of the page. Since you're working with Light and Dark only, assuming that this is set up with the AppThemeBinding
, you could just do something like this:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage">
<Grid>
<VerticalStackLayout
Grid.Row="0" Grid.Column="0">
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
<Label Text="Hello world!"/>
</VerticalStackLayout>
<Border
BackgroundColor="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}"
Opacity="0.75"
Grid.Row="0" Grid.Column="0" ZIndex="99"
HorizontalOptions="Start" VerticalOptions="Start"
WidthRequest="200" HeightRequest="100"
Stroke="white" StrokeThickness="3"/>
</Grid>
</ContentPage>
Essentially, your border just needs to be able to respond to changes to the app theme. You can find more information on how this works in the official documentation: https://learn.microsoft.com/en-us/dotnet/maui/user-interface/system-theme-changes?view=net-maui-7.0