Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
137 views
in Technique[技术] by (71.8m points)

c# - NavigateTo() Function is being called before constructor?

I am developing a Windows phone App and in my MainPage.xaml.cs file I have one private member that is being changed in the overrided method OnNavigateTo(). Although its value is changed, after that in the MainPage constructor its value resets to 0 (It's an int member). I guess that OnNavigateTo() method is being called BEFORE the constructor but if so I would have a nullReferenceException. What can cause that problem?

The OnNavigateTo() Function:

if (NavigationContext.QueryString.ContainsKey("leftDuration")) {

            //Get the selected value from IntroductionPage as a string
            var leftRecievedInformation = NavigationContext.QueryString["leftDuration"];

            //Convert the string to an enum object
            var firstRunLeftChosenDuration = (LensLifetime)Enum.Parse(typeof(LensLifetime), leftRecievedInformation);

            //Set the leftDuration value to the model object               
            _firstRunLeftDuration = getDurationAsNumber(firstRunLeftChosenDuration);

            MessageBox.Show(_firstRunLeftDuration + "");
            model.Left.LifeTime = _firstRunLeftDuration;

        }

My problematic member is the _firstRunLeftDuration value. Although, as you can see, i set the model.Left.LifeTime value, in the MainPage.xaml I still get the default 0 value... It' like completely ignoring this line of code.. I know the code is not particularly clear but I don't think its beneficial to add extra lines of useless code.

Here's the MainPage.xaml.cs file: public partial class MainPage : PhoneApplicationPage {

    public ContactLensesModel model;
    private int _firstRunLeftDuration, _firstRunRightDuration; //Members used for the initialization of the app

    public int FirstRunLeftDuration
    {
        get
        {
            return _firstRunLeftDuration;
        }
        set
        {
            _firstRunLeftDuration = value;
        }
    }

    public int FirstRunRightDuration
    {
        get
        {
            return _firstRunRightDuration;
        }
        set
        {
            _firstRunRightDuration = value;
        }

    }

    public ContactLensesModel Model
    {
        get
        {
            return model;
        }
        set
        {
            model = value;
        }

    }

    // Constructor
    public MainPage()
    {

        InitializeComponent();

        // Sample code to localize the ApplicationBar
        BuildLocalizedApplicationBar();

        //Should check if the user starts the app for the first time....

        //Create a new model
        Model = new ContactLensesModel();
        Model.setLeftNewStartingDate();
        Model.setRightNewStartingDate();


        //Should load the already saved model if the user in not entering for the first time...
        //....
        //....

        loadModel();

        //Connect the data Context
        leftLensDaysRemaining.DataContext = Model.Left;
        rightLensDaysRemaining.DataContext = Model.Right;


    }

    private int getDurationAsNumber(LensLifetime duration)
    {

        if (duration.Equals(LensLifetime.Day))
            return 1;
        else if (duration.Equals(LensLifetime.Two_Weeks))
            return 14;
        else
            return DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month);
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        //Get the arguments as strings and convert them to an enum, is true only when the user enters app for the first time.
        if (NavigationContext.QueryString.ContainsKey("leftDuration"))
        {

            //Get the selected value from IntroductionPage as a string
            var leftRecievedInformation = NavigationContext.QueryString["leftDuration"];

            //Convert the string to an enum object
            var firstRunLeftChosenDuration = (LensLifetime)Enum.Parse(typeof(LensLifetime), leftRecievedInformation);

            //Set the leftDuration value to the model object        

            FirstRunLeftDuration = getDurationAsNumber(firstRunLeftChosenDuration);
            Model.Left.LifeTime = FirstRunLeftDuration;

        }
        if (NavigationContext.QueryString.ContainsKey("rightDuration"))
        {

            //Get the selected value from IntroductionPage as a string
            var rightRecievedInformation = NavigationContext.QueryString["rightDuration"];

            //Convert the string to an enum object
            var firstRunRightChosenDuration = (LensLifetime)Enum.Parse(typeof(LensLifetime), rightRecievedInformation);

            //Set the leftDuration value to the model object
            _firstRunRightDuration = getDurationAsNumber(firstRunRightChosenDuration);
            Model.Right.LifeTime = _firstRunRightDuration;
        }


    }

    /// <summary>
    /// Loads the model from the isolated Storage
    /// </summary>
    private void loadModel()
    {
         //Load the model...
    }


    private void BuildLocalizedApplicationBar()
    {
        // Set the page's ApplicationBar to a new instance of ApplicationBar.
        ApplicationBar = new ApplicationBar();

        // Create a new button and set the text value to the localized string from AppResources.
        ApplicationBarIconButton appBarSettingsButton = new ApplicationBarIconButton(new Uri("/Assets/Icons/settingsIcon4.png", UriKind.Relative));
        appBarSettingsButton.Text = AppResources.AppBarSettingsButtonText;
        appBarSettingsButton.Click += appBarButton_Click;
        ApplicationBar.Buttons.Add(appBarSettingsButton);

        // Create a new menu item with the localized string from AppResources.
        //ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarMenuItemText);
        //ApplicationBar.MenuItems.Add(appBarMenuItem);
    }

    void appBarButton_Click(object sender, EventArgs e)
    {
        NavigationService.Navigate(new Uri("/SettingsPage.xaml", UriKind.RelativeOrAbsolute));
    }

    private void leftButtonChange_Click(object sender, RoutedEventArgs e)
    {
        model.setLeftNewStartingDate();
    }

    private void rightChangeButton_Click(object sender, RoutedEventArgs e)
    {
        model.setRightNewStartingDate();
    }
}

}

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The OnNavigatedTo method cannot be called before the constructor. The constructor is always executed first. I think your model.Left.LifeTime doesn't raise a PropertyChanged event. Hence, your View won't know you are giving it a value. Therefore it will show the default value of model.Left.Lifetime which is probably 0.

On the other hand, it's hard to tell without seeing the rest of your code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...