1

I would like to make a background image spread across the entire screen, and make the pages navigated to, display as a block in the center. Currently the background image code I have is not working and I'm unsure of how to go about displaying the other pages in a block.

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="Nova.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:Nova"
    xmlns:views="clr-namespace:Nova.View"
    Shell.FlyoutBehavior="Locked"
     BackgroundImageSource="Assets/BackgroundImage.png">

    <!--<ShellContent
        Title="Home"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="MainPage" />-->

    <Shell.FlyoutHeader>
        <Image Source="Assets/logo.png" HeightRequest="152"></Image>
    </Shell.FlyoutHeader>


    <Shell.FlyoutFooter>
        <Label Text="Username" Padding="20"></Label>
    </Shell.FlyoutFooter>

    <FlyoutItem Title="Dashboard" Icon="dotnet_bot.png">
        <Tab>
            <ShellContent 
                Title="Dashboard"
                ContentTemplate="{DataTemplate views:DashboardPage}"/>
        </Tab>

    </FlyoutItem>
    <FlyoutItem Title="Clients" Icon="dotnet_bot.png">
        <Tab>
            <ShellContent 
                Title="Clients"
                ContentTemplate="{DataTemplate views:ClientListPage}"/>
        </Tab>
    </FlyoutItem>
    <FlyoutItem Title="Staff" Icon="dotnet_bot.png">
        <Tab>
            <ShellContent 
                Title="Staff"
                ContentTemplate="{DataTemplate views:StaffListPage}"/>
        </Tab>
    </FlyoutItem>
    <FlyoutItem Title="Projects" Icon="dotnet_bot.png">
        <Tab>
            <ShellContent 
                Title="Projects"
                ContentTemplate="{DataTemplate views:ProjectsPage}"/>
        </Tab>
    </FlyoutItem>
    <FlyoutItem Title="Finances" Icon="dotnet_bot.png">
        <Tab>
            <ShellContent 
                Title="Finances"
                ContentTemplate="{DataTemplate views:FundsPage}"/>
        </Tab>
    </FlyoutItem>


</Shell>
Alexa Pettitt
  • 123
  • 1
  • 2
  • 7
  • Can you show what your result currently looks like and also show what you would like it to look like? – Julian Jul 27 '23 at 14:23
  • pages take up the entire screen (or window). If you want the page content as a centered block, you will need to add padding to the page. Likewise, you would set the background image on the page, not in the "navigation" – Jason Jul 27 '23 at 14:55
  • This is what I want it to look like: https://www.figma.com/file/CcA8gyVvAQ2CKNlWPMbVQ1/Untitled?type=design&node-id=0%3A1&mode=design&t=f8EkqfuAgxdGTLx0-1 – Alexa Pettitt Jul 28 '23 at 12:17

1 Answers1

1

What you want to do does not fit with Shells design. Nor any other navigation scheme (such as NavigationPage); app navigation is done "page to page", and a page fills the screen.

Instead, create a single page. Inside it, have a ContentView. Change that ContentView to point to (contain) different content.

In App.xaml.cs, change line:

MainPage = new AppShell();

to:

MainPage = new MainPage();

Where MainPage.xaml is something like:

<ContentPage ...
    x:Class="MyProject.MainPage">

  <!-- numbers control the area surrounding the "middle area" -->
  <Grid RowDefinitions="50,*,50" ColumnDefinitions="50,*,50">

    <!-- covers the whole screen -->
    <Image x:Name="backgroundImage" Grid.Row="0" Grid.RowSpan="3"
           Grid.Column="0" Grid.ColumnSpan="3" Source=... />

    <!-- "middle area". It is "on top of" backgroundImage -->
    <ContentView x:Name="content" Grid.Row="1" Grid.Column="1" />

  </Grid>
</ContentPage>

MainPage.xaml.cs:

public partial class MainPage : ContentPage
{
  public MainPage()
  {
    InitializeComponent();
    content.Content = new MyView1();
  }

  public void GoView2()
  {
    content.Content = new MyView2();
  }
}

MyView1.xaml:

<ContentView ...
    x:Class="MyProject.MyView1" />
  ...
</ContentView>

etc.

NOTE: MyView1 (etc.) don't have to be ContentView. Each can be any layout class, such as Grid or VerticalStackLayout.



OPTIONAL: To re-use views, use Service Provider instead of new MyView1()

See section "AppServiceProvider: USE SERVICE PROVIDER TO AVOID "new MyPage();"" of https://stackoverflow.com/a/76741424/199364.

As you become more familiar with Maui, you will see many suggestions to use Dependency Injection.

I've answered the question using content.Content = new MyView1();, because that is easier to understand, and get started with.

Applying the answer-section linked above, change this to:

content.Content = AppServiceProvider.GetService<MyView1>();

That section shows other coding you need to do, to make use of this technique.

I won't discuss here why you might want to do this.
Don't worry about this yet. Get new MyView1() working first.

ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196