【问题标题】:Xamarin forms TabbedPage View Model called multiple timeXamarin 形成多次调用的 TabbedPage 视图模型
【发布时间】:2020-06-13 06:17:13
【问题描述】:

我已经使用 ViewModel 实现了 Tabbedpage,但我的 ViewModel 构造函数调用了 4 次,因为我创建了 4 个选项卡,我还使用 prism 进行 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)
            {

            }

        }
}

下面是我的视图模型

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】:

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

    不要这样做:

    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 次的事情清单,因为没有提供更多信息。

    • 尝试删除 &lt;NavigationPage.TitleView&gt; 段。
    • 确保您正在导航到 DashboardPage。
    • 确保每个单独的 TabbedPage 都有自己的视图模型。
    • 尝试删除 prism:ViewModelLocator.AutowireViewModel="True" 并手动将视图模型添加到 TabbedPage。

    最后,构造函数应该能够运行得非常快,并且应该用于分配变量或实例化或非常快速的操作。你可以做的就是在你的虚拟机中分离代码:

    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();
     }
    

    希望对你有帮助。

    注意:所有这些代码都是即时编写的,从未编译过,可能存在一些错误。

    【讨论】:

      猜你喜欢
      • 2021-01-16
      • 2017-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多