Вопрос по windows-phone-7 – Делать код после OnNavigatedTo

1

У меня есть код получить IdUsers с другой страницы

String IdUsers;

        public Main_Wallets_Page()
        {
            InitializeComponent();            
            MessageBox.Show(IdUsers);
        }


protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            String Id;
            if (NavigationContext.QueryString.TryGetValue("IdUsers", out Id))
                IdUsers = Id;
        }

MessageBox всегда будет нулевым. Я хочу, чтобы MessageBox показал & quot; IdUsers & quot; после OnNavigationTo (Не помещайте MessageBox IN «OnNavigationTo»).

Как мне это сделать ?

Почему вы не хотите помещать вызов метода MessageBox.Show в OnNavigatedTo? Вам нужно получить доступ к переменным данным в том же потоке управления и видеть, что конструктор вызывается только один раз и перед методом OnNavigatedTo, тогда это не место для вызова MessageBox.Show. Paul Diston

Ваш Ответ

3   ответа
2

DO NOT местоMessageBox вOnNavigatedTo Попробуйте создать пустой проект сMainPage а такжеPage2, Поместить кнопку наMainPage перейти кPage2, ВPage2 местоMessageBox вOnNavigatedTo  Тогда все будет работать нормально, если вы начнете отладку с VS. НО, если вы развернете и запустите его, вы увидите, что при переходе кPage2 ты видишьMessageBox, Тогда ничего не делайте, просто подождите около 15 секунд.MessageBox будет реагировать какCanceled а такжеAPPLICATION WILL BE CRASHED! без какой-либо навигации кPage2 или жеMainPage, То же самое происходит, если вы используетеDispatcher.BeginInvoke вокругMessageBox.Show. I assume that OnNavigatedTo Событие имеет тайм-аут, который работает только при развертывании приложения. Таким образом, вы должны запустить свойMessageBox когда навигация конкурирует. Все работает, если вы делаете

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) {
    base.OnNavigatedTo(e);

    var lcTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 200) };
    lcTimer.Tick += (s2, e2) => {
         (s2 as DispatcherTimer).Stop();
         if (MessageBoxResult.OK == MessageBox.Show("Test, don't push", "", MessageBoxButton.OKCancel))
             MessageBox.Show("OK");
         else
             MessageBox.Show("Cancel");
    };
    lcTimer.Start();
}

Note: Если у вас есть код вOnNavigatedTo запустить код выше в концеOnNavigatedTo.

Мне понравилось то, что посоветовал Остин Томпсон (upvote)ThreadPool.QueueUserWorkItem, Но обратите внимание, что при таком подходе вам нужно поместить MessageBox внутриDispatcher.BeginInvoke в противном случае вы получите перекрестное исключение. Так что код следующий

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) {
    base.OnNavigatedTo(e);

    ThreadPool.QueueUserWorkItem((stateInfo) => {
        Dispatcher.BeginInvoke(() => {
            if (MessageBoxResult.OK == MessageBox.Show("Test don't push", "", MessageBoxButton.OKCancel))
                MessageBox.Show("OK");
            else
                MessageBox.Show("Cancel");
        });
    });
}
2

вы можете сохранить его в изолированном хранилище приложения. Затем, когда вызывается конструктор, вы можете прочитать его оттуда. В этом случае значение идентификатора пользователя будет инициализировано, и MessageBox не покажет вам значение NULL.

3

потому что, если пользователь не нажмет кнопку, ваше приложение будет аварийно завершено, так как платформа считает, что навигация не удалась. MessageBoxes в конструкторе одинаково плохи.

Я могу думать о двух вариантах (я использую # 1 для такого рода вещей):

Show the MessageBox in the Loaded event. But be careful it can be fired more than once. In the constructor you might add the handler for the Loaded event and then in the handler you'd detach from the handler so that it is called only once.

Use Dispatcher.BeginInvoke around the MessageBox.Show call so that it does not block navigation. That might still block the Dispatcher thread. If you really wanted to go this route you could use ThreadPool.QueueUserWorkItem or a TPL Task.

Я также использовалOnLayoutUpdated вместоLoaded событие, но я не могу точно вспомнить, почему :) Кажется, возможно, страница еще не отображалась вLoaded и это в другом случае.

Похожие вопросы