Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
.NET MAUI Cookbook

You're reading from   .NET MAUI Cookbook Build a full-featured app swiftly with MVVM, CRUD, AI, authentication, real-time updates, and more

Arrow left icon
Product type Paperback
Published in Dec 2024
Publisher Packt
ISBN-13 9781835461129
Length 384 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Alexander Russkov Alexander Russkov
Author Profile Icon Alexander Russkov
Alexander Russkov
Arrow right icon
View More author details
Toc

Table of Contents (11) Chapters Close

Preface 1. Chapter 1: Crafting the Page Layout FREE CHAPTER 2. Chapter 2: Mastering the MVVM Design Pattern 3. Chapter 3: Advanced XAML and UI Techniques 4. Chapter 4: Connecting to a Database and Implementing CRUD Operations 5. Chapter 5: Authentication and Authorization 6. Chapter 6: Real-Life Scenarios: AI, SignalR, and More 7. Chapter 7: Understanding Platform-Specific APIs and Custom Handlers 8. Chapter 8: Optimizing Performance 9. Index 10. Other Books You May Enjoy

Implementing layouts with dynamic orientation

Users can rotate mobile devices, and it’s important to adapt your UI according to the current orientation. The .NET MAUI platform doesn’t have a built-in class to set orientation-specific settings in XAML; however, it provides a visual state mechanism. Alternatively, you can set orientation-based properties in C#. In this recipe, we’ll implement both techniques.

Getting ready

To follow the steps described in this recipe, we just need to create a blank .NET MAUI application. The default template includes sample code in the MainPage.xaml and MainPage.xaml.cs files, but you can remove it and leave only a blank ContentPage in XAML and a constructor with the InitializeComponent method in CS. When copying code snippets with namespaces, don’t forget to replace them with the namespaces in your project.

The code for this recipe is available at https://github.com/PacktPublishing/.NET-MAUI-Cookbook/tree/main/Chapter01/c1-OrientationSpecificSettings.

How to do it…

Let’s use two different techniques to specify layout settings based on the orientation – set settings in XAML using visual states and set settings in C# by subscribing to the MainDisplayInfoChanged event, which is raised when the orientation is changed:

  1. To specify orientation-based settings in XAML, define VisualStateGroup with Portrait and Landscape visual states. In visual state setters, reference the elements you would like to customize by their names. Note that it’s necessary to explicitly specify the parent property class in each setter:

    MainPage.xaml

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="Portrait">
                    <VisualState.StateTriggers>
                        <OrientationStateTrigger
                               Orientation="Portrait" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter TargetName="rootGrid"
                            Property="Grid.RowDefinitions"
                                Value="*,*" />
                        <Setter TargetName="border2"
                                Property="Grid.Row"
                                Value="1"/>
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Landscape">
                    <VisualState.StateTriggers>
                        <OrientationStateTrigger
                            Orientation="Landscape" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter TargetName="rootGrid"
                           Property="Grid.RowDefinitions"
                                Value="*,*" />
                        <Setter TargetName="border2"
                                Property="Grid.Row"
                                Value="1"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </VisualStateManager.VisualStateGroups>
    <Grid x:Name="rootGrid">
        <Border x:Name="border1" BackgroundColor="Coral"/>
        <Border x:Name="border2" Background="DarkRed"/>
    </Grid>

    In the preceding code snippet, we set Grid.RowDefinitions and Grid.Row for the grid and border elements, referenced using the TargetName property. The VisualStateManager.VisualStateGroups property is defined at the page/view level, which allows you to set all orientation-based settings in one place instead of creating visual states in each element. You will see the following result if you run the project and try to rotate a device:

    Figure 1.6 – Landscape layout customization

    Figure 1.6 – Landscape layout customization

  1. To specify orientation-based settings in C#, subscribe to the DeviceDisplay.MainDisplayInfoChanged event and modify all required settings in the event handler:

    MainPage.xaml.cs

    protected override void OnNavigatedTo(NavigatedToEventArgs args) {
        base.OnNavigatedTo(args);
        SetOrientationSpecificSettings();
        DeviceDisplay.MainDisplayInfoChanged +=
          OnMainDisplayInfoChanged;
    }
    protected override void OnNavigatedFrom(NavigatedFromEventArgs args) {
        base.OnNavigatedFrom(args);
        DeviceDisplay.MainDisplayInfoChanged -= 
          OnMainDisplayInfoChanged;
    }
    private void OnMainDisplayInfoChanged(object? sender, 
      DisplayInfoChangedEventArgs e) {
        SetOrientationSpecificSettings();
    }
    void SetOrientationSpecificSettings() {
        if (DeviceDisplay.MainDisplayInfo.Orientation == 
          DisplayOrientation.Landscape)
            border1.BackgroundColor = Colors.Red;
        else
            border1.BackgroundColor = Colors.Green;
    }

    Don’t forget to unsubscribe from the MainDisplayInfoChanged event; otherwise, DeviceDisplay will always hold a reference of the view, and it will never be released, causing a memory leak.

How it works…

As you may know, .NET MAUI includes the visual state mechanism. Elements can have different predefined visual statues, which are not limited by Portrait and Landscape. For example, there are states such as Normal, Disabled, and Focused.

In C#, you can change the state using the VisualStateManager.GoToState method:

VisualStateManager.GoToState(someVisualElement, "<stateName>");

You can use any name for your custom state.

In XAML, you can go to a state using a state trigger. The platform provides a built-in OrientationStateTrigger trigger, so when the orientation is changed, this trigger is invoked, and a corresponding state is activated.

When a state is activated, it executes the setters:

<VisualState x:Name="Portrait">
    <VisualState.StateTriggers>
        <OrientationStateTrigger Orientation="Portrait" />
    </VisualState.StateTriggers>
    <VisualState.Setters>
        <Setter TargetName="rootGrid" Property="Grid.RowDefinitions" 
          Value="*,*" />
        <Setter TargetName="border2" Property="Grid.Row" Value="1"/>
    </VisualState.Setters>
</VisualState>

Each setter can be applied to a specific element on a page using the TargetName property. Since we define visual states at the ContentPage level, it’s necessary to explicitly set the name of the parent class in the property setter ("Grid.RowDefinitions").

As for the DeviceDisplay class, it includes basic information about your display, such as orientation, height, width, and density. So, if you need to fine-tune your layout based on these settings, you can use the DeviceDisplay.Current.MainDisplayInfo property:

double screenWidth = DeviceDisplay.Current.MainDisplayInfo.Width;
double screenHeight = DeviceDisplay.Current.MainDisplayInfo.Height;
double screenDensity = DeviceDisplay.Current.MainDisplayInfo.Density

There’s more…

While the bare .NET MAUI platform doesn’t include XAML extensions (similar to OnIdiom/OnPlatform) to set orientation-specific settings, you can use third-party suites, such as DevExpress, which include additional extensions that enable you to perform this task:

    <dx:DXButton Content="Click" Padding="{dx:OnOrientation 
      Portrait='8,4', Landscape='12,8'}"/>

You can learn more about this functionality in DevExpress’s documentation: https://docs.devexpress.com/MAUI/404287/common-concepts/specify-device-specific-settings#xaml-use-the-onorientation-extension.

You have been reading a chapter from
.NET MAUI Cookbook
Published in: Dec 2024
Publisher: Packt
ISBN-13: 9781835461129
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image