简体   繁体   中英

Dependency injection with multiple pages in .NET MAUI

There is already similar question and answer in this thread Injecting services into view models in .NET MAUI app . However it is using only one page. I have managed to get all dependencies working, but now I am missing my sidebar with menu items (pages). Can somebody drop some light why so and how to get side menu back leaving all the dependencies working?

Currently I have two pages and side menu looking like this:

在此处输入图像描述

If I am adding dependency injection this way:

App.xaml.cs:

public partial class App : Application
{
    public App(HomePage homePage)
    {
        InitializeComponent();

        MainPage = homePage;
  }
}

I am missing my side menu.

App.xaml:

<Application.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
        <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
      </ResourceDictionary.MergedDictionaries>

      <Style x:Key="FloutItemStyle" TargetType="Grid">
        <Setter Property="VisualStateManager.VisualStateGroups">
          <VisualStateGroupList>
            <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal" />
              <VisualState x:Name="Selected">
                <VisualState.Setters>
                  <Setter Property="BackgroundColor" Value="Transparent"/>
                  <Setter TargetName="_label" Property="Label.TextColor" Value="Red" />
                  <Setter TargetName="_image" Property="Image.Source" Value="Red" />
                </VisualState.Setters>
              </VisualState>
            </VisualStateGroup>
          </VisualStateGroupList>
        </Setter>
      </Style>
    </ResourceDictionary>
  </Application.Resources>

  <Application.MainPage>
    <Shell FlyoutWidth="90" FlyoutBehavior="{OnIdiom Phone=Disabled, Default=Locked}" 
           FlyoutBackground="#111111">

      <Shell.FlyoutHeaderTemplate>
        <DataTemplate>
          <BoxView HeightRequest="50" Color="Transparent"/>
        </DataTemplate>
      </Shell.FlyoutHeaderTemplate>

      <!-- Desktop/Tablet-->
      <FlyoutItem Title="Page1" Icon="{FontImage FontFamily=FontAwesomeSolid, Glyph={x:Static helpers:FontAwesomeIcons.User}, Size=50, Color=Red}">
        <ShellContent Title="Page1" Route="Page1" ContentTemplate="{DataTemplate page:Page1}">
          <ShellContent.Icon>
            <FontImageSource FontFamily="FontAwesomeSolid" Glyph="{x:Static helpers:FontAwesomeIcons.User}" Color="Red" Size="50"/>
          </ShellContent.Icon>
        </ShellContent>
      </FlyoutItem>
      <FlyoutItem Title="Page2" Icon="{FontImage FontFamily=FontAwesomeSolid, Glyph={x:Static helpers:FontAwesomeIcons.User}, Size=50}">
        <ShellContent Title="Page2" Route="Page2" ContentTemplate="{DataTemplate page:Page2}">
          <ShellContent.Icon>
            <FontImageSource FontFamily="FontAwesomeSolid" Glyph="{x:Static helpers:FontAwesomeIcons.User}" Color="White" Size="50"/>
          </ShellContent.Icon>
        </ShellContent>
      </FlyoutItem>

      <Shell.ItemTemplate>
        <DataTemplate>
          <Grid Style="{StaticResource FloutItemStyle}">
            <Grid.RowDefinitions>
              <RowDefinition Height="50" />
              <RowDefinition Height="25" />
            </Grid.RowDefinitions>
            <Image Source="{Binding FlyoutIcon}"
                   Grid.Row="0"
                   HeightRequest="40"
                   Margin="5,0,5,0"
                   HorizontalOptions="CenterAndExpand"
                   x:Name="_image"/>
            <Label Grid.Row="1"
                   Text="{Binding Title}"
                   TextColor="White"
                   FontSize="Body"
                   Padding="7,0,7,0"
                   VerticalTextAlignment="Center"
                   HorizontalTextAlignment="Center"
                   x:Name="_label">
            </Label>
          </Grid>
        </DataTemplate>
      </Shell.ItemTemplate>

    </Shell>
  </Application.MainPage>

That StackOverflow Q&A has misled you. That person wasn't using Shell; you are.

  • Start over.
  • Make New Project, with Maui template.
  • DON'T use your current MainPage. Your MainPage.xaml should be similar to the one the default template creates for you. There should NOT be any mention of Shell there.
  • Follow tutorial "Create a.Net MAUI app". Especially Page 2: Customize App Shell . See how "About Page" is added.
  • As in that tutorial, for each of your pages, add a ShellContent to Shell.xaml.
  • For MVVM, follow Tutorial: Use MVVM toolkit .
  • Notice example of adding BindingContext <viewModels:AboutViewModel /> to AboutPage xaml.
  • The ONLY part of Gerald Versluis' answer you MIGHT need, is:
// Do this for each Page and ViewModel.
// HOWEVER, based on those tutorials, these MIGHT NOT be needed in latest MAUI version.
// Its OK to add them, even if they aren't needed.
builder.Service.AddTransient<MainPage>();
builder.Service.AddTransient<MainPageViewModel>();
// Lines similar to this, if you have other services.
builder.Service.AddSingleton<IMyRestApiService, MyRestApiService>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM