MVVM Navigation Force关闭Xamarin表单

时间:2017-12-08 07:00:58

标签: c# mvvm xamarin.forms

我尝试在我的xamarin表单中使用mvvm,但我仍然对每个页面中的导航感到困惑,我已经创建接口和NavigationService来处理我的Xamarin表单中的所有导航,没有错误代码行但是当我单击按钮并尝试导航到其他页面始终崩溃。这是我的一些代码 我的界面

namespace KGVC.Interfaces
{
    public interface INavigationService
    {
        void NavigateToDashboard();
        void NavigateToLogout();
        void NavigateBack();
        void gotoNews();
        void goEvent();
        void gotoKGCash();
        void gotoCardCommnunity();
        void gotoSetting();
        void gotoNearbyLocation();
    }
}

我的导航服务

namespace KGVC.Services
{
    public class NavigationService : INavigationService
    {
        public  void goEvent()
        {
            var currentPage = GetCurrentPage();

             currentPage.Navigation.PushAsync(new EventPage());
        }

        public  void gotoCardCommnunity()
        {
            var currentPage = GetCurrentPage();

             currentPage.Navigation.PushAsync(new CardCommunityPage());
        }

        public  void gotoKGCash()
        {
            var currentPage = GetCurrentPage();

             currentPage.Navigation.PushAsync(new KGCashPage());
        }

        public  void gotoNearbyLocation()
        {
            var currentPage = GetCurrentPage();

             currentPage.Navigation.PushAsync(new StoreMaps());
        }

        public  void gotoNews()
        {
            var currentPage = GetCurrentPage();

             currentPage.Navigation.PushAsync(new RssFeedView());
        }

        public   void gotoSetting()
        {
            var currentPage = GetCurrentPage();

             currentPage.Navigation.PushAsync(new SettingPages());
        }

        public void NavigateBack()
        {
            throw new NotImplementedException();
        }

        public  void NavigateToDashboard()
        {

            var currentPage = GetCurrentPage();

             Application.Current.MainPage = new MainPage();
        }

        public void NavigateToLogout()
        {
            var currentPage = GetCurrentPage();
            Application.Current.MainPage = new NewPageLogin();
        }

        private Page GetCurrentPage()
        {
            var currentPage = Application.Current.MainPage.Navigation.NavigationStack.LastOrDefault();

            return currentPage;
        }
    }
}

我的观点模型

public class GridMenuViewModel
    {


        public ICommand gotoNews { get; private set; }
        public ICommand goEvent { get; private set; }
        public ICommand gotoKGCash { get; private set; }
        public ICommand gotoSetting { get; private set; }
        public ICommand gotoNearbyLocation { get; private set; }
        public GridMenuViewModel()
        {
            gotoNews = new Command(() =>
            {
                var navigationService = new NavigationService();

                navigationService.gotoNews();
            });
            goEvent = new Command(() =>
            {
                var navigationService = new NavigationService();

                navigationService.goEvent();
            });

            gotoKGCash = new Command(() =>
            {
                var navigationService = new NavigationService();

                navigationService.gotoKGCash();
            });
            gotoSetting = new Command(() =>
            {
                var navigationService = new NavigationService();

                navigationService.gotoSetting();
            });
            gotoNearbyLocation = new Command(() =>
            {
                var navigationService = new NavigationService();

                navigationService.gotoNearbyLocation();
            });
        }
    }

我的观点

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             NavigationPage.HasNavigationBar="True"
             NavigationPage.BackButtonTitle="False"
               BindingContext="{Binding GridMenuViewModel, Source={StaticResource Locator}}"
             xmlns:control="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
             xmlns:local="clr-namespace:KGVC.Views.MainPages"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="KGVC.Views.MainPages.GridMenu"
             Title="HOME"
            >


    <ContentPage.Content>
        <StackLayout >
            <StackLayout  BackgroundColor="##CEB053">
                <StackLayout  HeightRequest="35" BackgroundColor="##CEB053" Orientation="Horizontal">
                    <Label  FontAttributes="Italic" TextColor="Black" Margin="9" Text="Hello," FontSize="15"/>
                    <Label  TextColor="Black"  Margin="9" Text="John Doe" FontSize="15" FontAttributes="Bold"/>

                </StackLayout>

                <StackLayout  Padding="0"  HeightRequest="30" BackgroundColor="#E3E6E3" Orientation="Horizontal">
                    <Image Margin="5" Source="ic_logo.png"/>
                    <Label  Text="Points" Margin="5" FontSize="13" TextColor="Black"/>
                </StackLayout>

            </StackLayout>


            <StackLayout  HeightRequest="220" VerticalOptions="StartAndExpand">

                <control:CarouselView HeightRequest="185" ItemsSource="{Binding MyDataSource}" Position="{Binding Position, Mode=TwoWay}">
                    <control:CarouselView.ItemTemplate>
                        <DataTemplate>
                            <Image  Source="{Binding Image}"/>

                        </DataTemplate>
                    </control:CarouselView.ItemTemplate>
                </control:CarouselView>
                <local:CarouselIndicators IndicatorHeight="9" IndicatorWidth="9" UnselectedIndicator="unselected_circle.png" SelectedIndicator="selected_circle.png" Position="{Binding Position}" ItemsSource="{Binding MyDataSource}" />
            </StackLayout>

            <ScrollView IsClippedToBounds="True" VerticalOptions="StartAndExpand" Orientation="Vertical" >

                    <Grid x:Name="controlGrid" VerticalOptions="StartAndExpand" HeightRequest="370" Margin="15">

                        <Grid.RowDefinitions>
                            <RowDefinition Height="0" />
                            <RowDefinition Height="100" />
                            <RowDefinition Height="100" />
                            <RowDefinition Height="100" />

                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>

                            <ColumnDefinition Width="110" />
                            <ColumnDefinition Width="110" />
                            <ColumnDefinition Width="110" />

                        </Grid.ColumnDefinitions>

                        <StackLayout Orientation="Vertical"  Grid.Row="1" Grid.Column="0" >
                            <Button Image="ic_account.png" Margin="5" 
        Style="{StaticResource plainButton}" />
                            <Label FontSize="12" Text="MY ACCOUNT" HorizontalOptions="Center"/>
                        </StackLayout>

                        <StackLayout Orientation="Vertical" Grid.Row="1" Grid.Column="1">
                        <Button Margin="5" Command="{Binding gotoCardCommunity}" Image="ic_card.png" 
        Style="{StaticResource plainButton}" />
                            <Label FontSize="12" Text="CARD" HorizontalOptions="Center"/>
                        </StackLayout>

                        <StackLayout Orientation="Vertical" Grid.Row="1" Grid.Column="2">
                        <Button Margin="5" Command="{Binding goEvent}" Image="ic_event" 
        Style="{StaticResource plainButton}" />
                            <Label FontSize="12" Text="PROMO" HorizontalOptions="Center"/>
                        </StackLayout>

                        <StackLayout Grid.Row="2" Grid.Column="0" Orientation="Vertical">
                        <Button Margin="5" Command="{Binding gotoNearbyLocation}" Image="ic_store" 
        Style="{StaticResource plainButton}" />
                            <Label FontSize="12" Text="STORE LOCATIONS" HorizontalOptions="Center"/>
                        </StackLayout>

                        <StackLayout Orientation="Vertical" Grid.Row="2" Grid.Column="1">
                        <Button Margin="5" Command="{Binding gotoNews}"  Image="ic_news" 
        Style="{StaticResource plainButton}" />
                            <Label FontSize="12" Text="NEWS" HorizontalOptions="Center"/>

                        </StackLayout>


                        <StackLayout Grid.Row="2" Grid.Column="2" Orientation="Vertical">
                        <Button Margin="5"  Command="{Binding gotoKGCash}" Image="ic_kgcash" 
        Style="{StaticResource plainButton}" />
                            <Label FontSize="12" Text="E-WALLET" HorizontalOptions="Center"/>
                        </StackLayout>

                        <StackLayout Orientation="Vertical" Grid.Row="3" Grid.Column="0">
                            <Button Margin="5"  Image="ic_ecommerce" 
        Style="{StaticResource plainButton}" />
                            <Label FontSize="12" Text="E-COMMERCE" HorizontalOptions="Center"/>
                        </StackLayout>

                        <StackLayout Orientation="Vertical" Grid.Row="3" Grid.Column="1">
                        <Button Margin="5"  Command="{Binding gotoSetting}" Image="ic_pointsummary.png" 
        Style="{StaticResource plainButton}" />
                            <Label FontSize="12" Text="POINT SUMMARY" HorizontalOptions="Center"/>
                        </StackLayout>


                        <StackLayout Orientation="Vertical" Grid.Row="3" Grid.Column="2">
                        <Button Margin="5"  Command="{Binding gotoSetting}" Image="ic_setting" 
        Style="{StaticResource plainButton}" />
                            <Label FontSize="12" Text="SETTINGS" HorizontalOptions="Center"/>
                        </StackLayout>



                    </Grid>






            </ScrollView>



        </StackLayout>


    </ContentPage.Content>
</ContentPage>

我已经尝试更改导航服务以使用pushmodalasync,使导航异步但仍然崩溃,任何人都可以帮助我吗?而且我没有使用prism,mvvmlight和其他第三方mvvm nuget

1 个答案:

答案 0 :(得分:1)

这取决于您的MainPage。您是否检查过GetCurrentPage()是否确实返回了某些内容?

尝试将GetCurrentPage()更改为:

Page GetCurrentPage() =>
  Application.Current.MainPage.Navigation?.NavigationStack?.LastOrDefault() ??
  Application.Current.MainPage;

我发现的另一个问题:
1. C# naming conventions与Java不同。方法名称应以大写字母开头。目前你有一个纯粹的混合。
2.按照bug的方式,按照您的方式在XAML中初始化BindingContext将创建ViewModel两次。将其更改为:

<ContentPage
  xmlns:vm="your-namespace.vm"
  ...>
  <ContentPage.BindingContext>
    <vm:GridMenuViewModel />
  </ContentPage.BindingContext>
</ContentPage>

3。无需为每个命令重新创建NavigationService。在ViewModel中重用它。
4.你有一些损坏的XAML:

<StackLayout  BackgroundColor="##CEB053">

修复十六进制代码。一般来说,您可以启用XAMLC,以便在构建代码时收到有关XAML错误的通知。
5.为了使用PushAsync,您的MainPage应该由NavigationPage包裹。
6.您需要等待异步代码执行:

public async Task GoToCardCommnunity()
{
  var currentPage = GetCurrentPage();
  await currentPage.Navigation.PushAsync(new CardCommunityPage());
}

检查上面的列表并注意应用程序输出和异常。