Xamarin形式的TabbedPage视图模型称为多次

问题描述 投票:0回答:1

我已经使用ViewModel实现Tabbedpage,但我的ViewModel构造函数调用了4次,因为我创建了4个标签,所以我也使用了棱镜进行ViewModel绑定。

下面是设计文件

<?xml version="1.0" encoding="UTF-8"?>

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms" 
            xmlns:material="clr-namespace:XF.Material.Forms.UI;assembly=XF.Material"
            xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
            xmlns:ffTransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations" 
            prism:ViewModelLocator.AutowireViewModel="True"
             xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
            xmlns:extended="clr-namespace:Xamarin.Forms.Extended;assembly=Xamarin.Forms.Extended.InfiniteScrolling"
            xmlns:customcontrols="clr-namespace:QuranicQuizzes.CustomControls"
            xmlns:local="clr-namespace:QuranicQuizzes.Views" NavigationPage.HasNavigationBar="True"
             x:Class="QuranicQuizzes.Views.DashboardPage">
      <NavigationPage.TitleView>
        <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
            <Label Text="Dashboard" TextColor="White" HorizontalTextAlignment="Center" HorizontalOptions="CenterAndExpand" VerticalTextAlignment="Center" FontFamily="{StaticResource QuranFontBold}" FontSize="Medium" />
            <StackLayout Orientation="Horizontal">
               <material:MaterialMenuButton x:Name="Menus" ButtonType="Text" Image="list" TintColor="White" BackgroundColor="Transparent" CornerRadius="24" Choices="{Binding Actions}"  MenuSelected="MaterialMenuButton_MenuSelected"  />
            </StackLayout>

        </StackLayout>
    </NavigationPage.TitleView>
        <local:HomeTabPage/>
        <local:QuizzesTabPage/>
        <local:LiveGameTabPage/>
        <local:AssignmentTabPage/>

</TabbedPage>

下面是我的代码

public partial class DashboardPage : TabbedPage
    {
        private DashboardPageViewModel vm;
        public DashboardPage()
        {
            try
            {
                InitializeComponent();
                vm = BindingContext as DashboardPageViewModel;

            }
            catch (Exception ex)
            {

            }

        }
}

下面是我的ViewModel

public class DashboardPageViewModel : ViewModelBase
{
 INavigationService _navigationService;
        IClientAPI _clientAPI;
        Dashboards dashboard;
   public DashboardPageViewModel(INavigationService navigationService, IClientAPI clientAPI) : base(navigationService)
        {
            _navigationService = navigationService;
            _clientAPI = clientAPI;

            if (CrossConnectivity.Current.IsConnected)
            {
                var StartDate = DateTime.Now.AddDays(-7).ToString("yyyy-MM-dd");
                var Enddate = DateTime.Now.ToString("yyyy-MM-dd");
                if (dashboard == null)
                {
                    dashboard = new Dashboards();
                    getDashboardData(StartDate, Enddate);
                }
            }
        }
}
mvvm xamarin.forms xamarin.android tabbedpage
1个回答
0
投票

我明白了您要做什么。您想初始化虚拟机实例,以便可以从视图访问虚拟机。

而不是这样做:

vm = BindingContext as DashboardPageViewModel;

我们可以通过执行以下操作来更改现有BindingContext属性的类型:

public partial class DashboardPage
{
     new DashboardPageViewModel BindingContext
     {
        get => (DashboardPageViewModel) base.BindingContext;
        set => base.BindingContext = value;
     }

     public DashboardPage()
     {
        InitializeComponent();
     }
}

现在您可以访问BindingContext.DoSomething,因为它的类型现在是DashboardPageViewModel

现在已解决,您的视图模型不应被调用4次!这里不对劲。这是一份待办事项清单,可能会导致构造函数被调用了4次,因为没有提供太多信息。

  • 尝试删除<NavigationPage.TitleView>段。
  • 确保您导航到DashboardPage。
  • 确保每个单独的TabbedPage都有其自己的视图模型。
  • 尝试删除prism:ViewModelLocator.AutowireViewModel="True",然后将视图模型手动添加到TabbedPage。

最后,构造函数应该能够非常快速地运行,并且应该only用于分配变量或实例化或非常快速的操作。您可能要做的就是在VM中分离代码:

public class DashboardPageViewModel : ViewModelBase
{
    IClientAPI _clientAPI;
    Dashboards dashboard;

    public DashboardPageViewModel(INavigationService navigationService, IClientAPI clientAPI) : base(navigationService)
    {
        _clientAPI = clientAPI;
    }

    public void Init()
    {
        if (CrossConnectivity.Current.IsConnected)
        {
            var StartDate = DateTime.Now.AddDays(-7).ToString("yyyy-MM-dd");
            var Enddate = DateTime.Now.ToString("yyyy-MM-dd");
            if (dashboard == null)
            {
                dashboard = new Dashboards();
                getDashboardData(StartDate, Enddate);
            }
        }
    }        
}

然后您可以在视图中添加此方法:

protected override void OnBindingContextChanged()
{
    base.OnBindingContextChanged();

     if(BindingContext == null)
     {
         return;
     }

     BindingContext.Init();
 }

我希望这对您有帮助。

NB:所有这些代码都是即时编写的,并且从未进行过编译,可能会有一些错误。

© www.soinside.com 2019 - 2024. All rights reserved.