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 始终为 Null。我想在 OnNavigationTo 之后让 MessageBox 显示“IdUsers”(不要将 MessageBox 放在“OnNavigationTo”中)。

我该怎么做 ?

4

3 回答 3

3

您不应该在 OnNavigatedTo 中使用 MessageBoxes,因为如果用户不按下按钮,您的应用程序将崩溃,因为框架认为导航失败。构造函数中的消息框同样糟糕。

我可以想到两个选项(我将#1用于这些事情):

  1. Loaded事件中显示 MessageBox。但要小心它可以被多次解雇。在构造函数中,您可以为 Loaded 事件添加处理程序,然后在处理程序中从处理程序中分离,以便仅调用一次。

  2. Dispatcher.BeginInvoke在调用周围使用MessageBox.Show,以免阻塞导航。这可能仍会阻塞 Dispatcher 线程。如果你真的想走这条路,你可以使用ThreadPool.QueueUserWorkItemTPL Task

我也使用OnLayoutUpdated了该Loaded事件的位置,但我不记得确切原因:) 似乎该页面尚未显示,Loaded而在另一个事件中已显示。

于 2012-05-08T16:33:47.820 回答
2

DO NOT place MessageBox into OnNavigatedTo event. Try to create an empty project with MainPage and Page2. Place button on MainPage to navigate to Page2. In Page2 place MessageBox in OnNavigatedTo event. Then everythig will work fine if you Start Debugging from VS. BUT if you deploy and run it you will see that when you navigate to Page2 you see MessageBox. Then don't do anything, just wait for about 15 sec. MessageBox will react as Canceled and APPLICATION WILL BE CRASHED! without any navigation to Page2 or MainPage. The same thing happens if you use Dispatcher.BeginInvoke around the MessageBox.Show. I assume that OnNavigatedTo event has a timeout which works only when app is deployed. So you should run your MessageBox when Navigation is competed. Everything works if you do

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: If you have some code in OnNavigatedTo run above code at the end of OnNavigatedTo.

I liked what Austin Thompson(upvote) has adviced with ThreadPool.QueueUserWorkItem. But note that with this approach you need to place MessageBox inside the Dispatcher.BeginInvoke otherwise you will receive cross-thread exception. So the code is the following

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");
        });
    });
}
于 2012-10-27T13:01:36.880 回答
2

如果此值已初始化,您可以将其存储在应用程序隔离存储中。然后,当调用构造函数时,您可以从那里读取它。在这种情况下,用户 ID 的值将被初始化并且 MessageBox 不会显示为 NULL。

于 2012-05-08T09:04:18.423 回答