在.NET MAUI中为导航添加背景图像

huangapple go评论133阅读模式
英文:

Add background image to navigation in .net maui

问题

我想让背景图片铺满整个屏幕,并使导航到的页面显示为中心的块。目前,我拥有的背景图片代码不起作用,我不确定如何显示其他页面为块。

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <Shell
  3. x:Class="Nova.AppShell"
  4. xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
  5. xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  6. xmlns:local="clr-namespace:Nova"
  7. xmlns:views="clr-namespace:Nova.View"
  8. Shell.FlyoutBehavior="Locked"
  9. BackgroundImageSource="Assets/BackgroundImage.png">
  10. <!--<ShellContent
  11. Title="Home"
  12. ContentTemplate="{DataTemplate local:MainPage}"
  13. Route="MainPage" />-->
  14. <Shell.FlyoutHeader>
  15. <Image Source="Assets/logo.png" HeightRequest="152"></Image>
  16. </Shell.FlyoutHeader>
  17. <Shell.FlyoutFooter>
  18. <Label Text="Username" Padding="20"></Label>
  19. </Shell.FlyoutFooter>
  20. <FlyoutItem Title="Dashboard" Icon="dotnet_bot.png">
  21. <Tab>
  22. <ShellContent
  23. Title="Dashboard"
  24. ContentTemplate="{DataTemplate views:DashboardPage}"/>
  25. </Tab>
  26. </FlyoutItem>
  27. <FlyoutItem Title="Clients" Icon="dotnet_bot.png">
  28. <Tab>
  29. <ShellContent
  30. Title="Clients"
  31. ContentTemplate="{DataTemplate views:ClientListPage}"/>
  32. </Tab>
  33. </FlyoutItem>
  34. <FlyoutItem Title="Staff" Icon="dotnet_bot.png">
  35. <Tab>
  36. <ShellContent
  37. Title="Staff"
  38. ContentTemplate="{DataTemplate views:StaffListPage}"/>
  39. </Tab>
  40. </FlyoutItem>
  41. <FlyoutItem Title="Projects" Icon="dotnet_bot.png">
  42. <Tab>
  43. <ShellContent
  44. Title="Projects"
  45. ContentTemplate="{DataTemplate views:ProjectsPage}"/>
  46. </Tab>
  47. </FlyoutItem>
  48. <FlyoutItem Title="Finances" Icon="dotnet_bot.png">
  49. <Tab>
  50. <ShellContent
  51. Title="Finances"
  52. ContentTemplate="{DataTemplate views:FundsPage}"/>
  53. </Tab>
  54. </FlyoutItem>
  55. </Shell>
英文:

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.

  1. &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
  2. &lt;Shell
  3. x:Class=&quot;Nova.AppShell&quot;
  4. xmlns=&quot;http://schemas.microsoft.com/dotnet/2021/maui&quot;
  5. xmlns:x=&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot;
  6. xmlns:local=&quot;clr-namespace:Nova&quot;
  7. xmlns:views=&quot;clr-namespace:Nova.View&quot;
  8. Shell.FlyoutBehavior=&quot;Locked&quot;
  9. BackgroundImageSource=&quot;Assets/BackgroundImage.png&quot;&gt;
  10. &lt;!--&lt;ShellContent
  11. Title=&quot;Home&quot;
  12. ContentTemplate=&quot;{DataTemplate local:MainPage}&quot;
  13. Route=&quot;MainPage&quot; /&gt;--&gt;
  14. &lt;Shell.FlyoutHeader&gt;
  15. &lt;Image Source=&quot;Assets/logo.png&quot; HeightRequest=&quot;152&quot;&gt;&lt;/Image&gt;
  16. &lt;/Shell.FlyoutHeader&gt;
  17. &lt;Shell.FlyoutFooter&gt;
  18. &lt;Label Text=&quot;Username&quot; Padding=&quot;20&quot;&gt;&lt;/Label&gt;
  19. &lt;/Shell.FlyoutFooter&gt;
  20. &lt;FlyoutItem Title=&quot;Dashboard&quot; Icon=&quot;dotnet_bot.png&quot;&gt;
  21. &lt;Tab&gt;
  22. &lt;ShellContent
  23. Title=&quot;Dashboard&quot;
  24. ContentTemplate=&quot;{DataTemplate views:DashboardPage}&quot;/&gt;
  25. &lt;/Tab&gt;
  26. &lt;/FlyoutItem&gt;
  27. &lt;FlyoutItem Title=&quot;Clients&quot; Icon=&quot;dotnet_bot.png&quot;&gt;
  28. &lt;Tab&gt;
  29. &lt;ShellContent
  30. Title=&quot;Clients&quot;
  31. ContentTemplate=&quot;{DataTemplate views:ClientListPage}&quot;/&gt;
  32. &lt;/Tab&gt;
  33. &lt;/FlyoutItem&gt;
  34. &lt;FlyoutItem Title=&quot;Staff&quot; Icon=&quot;dotnet_bot.png&quot;&gt;
  35. &lt;Tab&gt;
  36. &lt;ShellContent
  37. Title=&quot;Staff&quot;
  38. ContentTemplate=&quot;{DataTemplate views:StaffListPage}&quot;/&gt;
  39. &lt;/Tab&gt;
  40. &lt;/FlyoutItem&gt;
  41. &lt;FlyoutItem Title=&quot;Projects&quot; Icon=&quot;dotnet_bot.png&quot;&gt;
  42. &lt;Tab&gt;
  43. &lt;ShellContent
  44. Title=&quot;Projects&quot;
  45. ContentTemplate=&quot;{DataTemplate views:ProjectsPage}&quot;/&gt;
  46. &lt;/Tab&gt;
  47. &lt;/FlyoutItem&gt;
  48. &lt;FlyoutItem Title=&quot;Finances&quot; Icon=&quot;dotnet_bot.png&quot;&gt;
  49. &lt;Tab&gt;
  50. &lt;ShellContent
  51. Title=&quot;Finances&quot;
  52. ContentTemplate=&quot;{DataTemplate views:FundsPage}&quot;/&gt;
  53. &lt;/Tab&gt;
  54. &lt;/FlyoutItem&gt;
  55. &lt;/Shell&gt;

答案1

得分: 1

你想要做的事情与 Shell 的设计不符合,也不符合任何其他导航方案(如 NavigationPage);应用程序导航是“页面对页面”,每个页面填充整个屏幕。

相反,创建一个单一页面。在该页面内,使用 ContentView。将该 ContentView 更改为指向(包含)不同的内容。

App.xaml.cs 中,将以下行更改为:

  1. MainPage = new AppShell();

更改为:

  1. MainPage = new MainPage();

其中 MainPage.xaml 大致如下:

  1. <ContentPage ...
  2. x:Class="MyProject.MainPage">
  3. <!-- 数字控制“中间区域”周围的区域 -->
  4. <Grid RowDefinitions="50,*,50" ColumnDefinitions="50,*,50">
  5. <!-- 占据整个屏幕 -->
  6. <Image x:Name="backgroundImage" Grid.Row="0" Grid.RowSpan="3"
  7. Grid.Column="0" Grid.ColumnSpan="3" Source=... />
  8. <!-- “中间区域”。它位于backgroundImage之上 -->
  9. <ContentView x:Name="content" Grid.Row="1" Grid.Column="1" />
  10. </Grid>
  11. </ContentPage>

MainPage.xaml.cs:

  1. public partial class MainPage : ContentPage
  2. {
  3. public MainPage()
  4. {
  5. InitializeComponent();
  6. content.Content = new MyView1();
  7. }
  8. public void GoView2()
  9. {
  10. content.Content = new MyView2();
  11. }
  12. }

MyView1.xaml:

  1. <ContentView ...
  2. x:Class="MyProject.MyView1" />
  3. ...
  4. </ContentView>

等等。

注意:MyView1(等等)不必是 ContentView。每个都可以是任何布局类,如 GridVerticalStackLayout



可选:要重用视图,请使用服务提供程序而不是 new MyView1()

请参阅 https://stackoverflow.com/a/76741424/199364 中的“AppServiceProvider: 使用服务提供程序避免 'new MyPage();'”部分。

随着您对 Maui 的了解越来越深入,您将看到许多建议使用依赖注入

我使用 content.Content = new MyView1(); 来回答问题,因为这更容易理解和入门。

应用上面链接中的答案部分,将其更改为:

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

该部分显示了您需要执行的其他编码,以利用这一技术。

我不会在这里讨论为什么您可能想要这样做。
现在不必担心这个问题,首先让 new MyView1() 起作用。

英文:

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:

  1. MainPage = new AppShell();

to:

  1. MainPage = new MainPage();

Where MainPage.xaml is something like:

  1. &lt;ContentPage ...
  2. x:Class=&quot;MyProject.MainPage&quot;&gt;
  3. &lt;!-- numbers control the area surrounding the &quot;middle area&quot; --&gt;
  4. &lt;Grid RowDefinitions=&quot;50,*,50&quot; ColumnDefinitions=&quot;50,*,50&quot;&gt;
  5. &lt;!-- covers the whole screen --&gt;
  6. &lt;Image x:Name=&quot;backgroundImage&quot; Grid.Row=&quot;0&quot; Grid.RowSpan=&quot;3&quot;
  7. Grid.Column=&quot;0&quot; Grid.ColumnSpan=&quot;3&quot; Source=... /&gt;
  8. &lt;!-- &quot;middle area&quot;. It is &quot;on top of&quot; backgroundImage --&gt;
  9. &lt;ContentView x:Name=&quot;content&quot; Grid.Row=&quot;1&quot; Grid.Column=&quot;1&quot; /&gt;
  10. &lt;/Grid&gt;
  11. &lt;/ContentPage&gt;

MainPage.xaml.cs:

  1. public partial class MainPage : ContentPage
  2. {
  3. public MainPage()
  4. {
  5. InitializeComponent();
  6. content.Content = new MyView1();
  7. }
  8. public void GoView2()
  9. {
  10. content.Content = new MyView2();
  11. }
  12. }

MyView1.xaml:

  1. &lt;ContentView ...
  2. x:Class=&quot;MyProject.MyView1&quot; /&gt;
  3. ...
  4. &lt;/ContentView&gt;

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:

  1. content.Content = AppServiceProvider.GetService&lt;MyView1&gt;();

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.

huangapple
  • 本文由 发表于 2023年7月27日 19:19:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76779222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定