【问题标题】:Handling Delegates on Windows Phone在 Windows Phone 上处理代表
【发布时间】:2012-11-24 19:07:28
【问题描述】:

我的应用程序中的 QueryString 有问题。我的主页中有两个按钮,当用户单击一个按钮时,应用程序导航到第二页并将按钮 ID 存储在 Querystring 上。

现在,我遇到的问题是,如果用户单击按钮,则查询字符串“ID”键被设置为相应的 ID 值,但该 ID 值将变为持久性。

点击Button1 => NavigationService("/Page2.xaml?ID=1",UriKind.Relative) => 查看page2的onNavigated事件中传入的ID值,发现Querystring成功设置为第二页的ID。

但是如果你点击后退按钮然后按 button2

单击 Button2 => NavigationService("/Page2.xaml?ID=2",UriKind.Relative) => 检查 page2 的 onNavidated 事件中的 QueryString 值,您会发现 ID 键的值仍然为 1。

如果我是通过按 button2 开始的,那么 ID 键的持久值将为 2。

我完全不知道会发生什么。我在页面之间进行了动画页面转换,但我不知道这会如何影响事情。有人知道会发生什么吗?如果我导航回主页,有没有办法重置整个应用程序?

在主页中

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            animation1.Stop();
            animation2.Stop();
            animation1.Begin();
        }


        private void button1_Click(object sender, RoutedEventArgs e)
        {          
            animation2.Begin();
            animation2.Completed += (x, y) => NavigationService.Navigate(new Uri("/fooApp;component/Page2.xaml?id=1", UriKind.Relative));                           
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            animation2.Begin();
            animation2.Completed += (x, y) => NavigationService.Navigate(new Uri("/fooApp;component/Page2.xaml?id=2", UriKind.Relative));          
        }

        private void button3_Click(object sender, RoutedEventArgs e)
        {
            animation2.Begin();
            animation2.Completed += (x, y) =>   NavigationService.Navigate(new Uri("/fooApp;component/Page2.xaml?id=3", UriKind.Relative));      
        }

在第2页

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

       base.OnNavigatedTo(e);

       animation1.Stop();
       animation2.Stop();
       animation1.Begin();

    }

顺便说一句,我已经注释掉了整个 Page2 Page Loaded 事件。

更新

我注意到的一件事是程序甚至没有运行第二次导航调用,它只运行第一次,我知道这是因为如果我将 button2 中的 Uri 源更改为空字符串并使用 button1 运行程序作为首先按下的按钮,无论我返回并按下哪个按钮,我都会将查询字符串值卡在 1。当我查看 page2 中 OnNavigatedTo 事件中的 NavigationEventArgs e 对象时,它的 URI 源将始终是第一个uri 来源。

我现在的猜测是,animation2.Completed 事件正在充当某种多播委托,首先放入其中的就是运行的任何内容。此外,我删除了动画,只使用了 Navigation 语句,该程序运行良好,但没有动画。有人知道我如何清除 animation2.Completed 事件吗?或者对替代实现有任何想法。

【问题讨论】:

  • 这不应该发生,所以你的代码一定有问题。如果您不向我们展示,我们将无法判断问题所在。
  • 接收端的代码(Page2.xaml)呢?另外,从我在这里看到的情况来看,您似乎没有使用任何类型的 MVVM 框架 - 对吗?
  • 我不知道 MVVM 是什么,所以我认为我没有使用它。我在 page2 的其他事件处理程序中编写的代码是否可能导致问题?我认为 onNavigated 事件是要运行的第一个代码,所以这怎么可能。
  • 我目前在 page2 的 onNavigated 事件的开头设置了一个断点,并且我已将 NavigationContext.QueryString["id"] 添加到我的监视列表中,当我按下一个按钮时,它的 ID 到达 page2 但是当我回去再按一个,到达page2的ID和之前的ID是一样的。
  • My guess right now is that the animation2.Completed event is acting as some sort of multicast delegate of sorts => 一个事件一个多播委托。

标签: c# windows-phone-7


【解决方案1】:

基本上,您正在向情节提要添加Completed 处理程序。 Completed 处理程序导航到第 2 页。然后您返回并按下第二个按钮。由于您返回上一页,因此您正在重新使用相同的页面实例,因此也使用相同的 Storyboard 实例。 现在您正在向您的Storyboard 添加第二个Completed 处理程序。所以当动画结束时,Storyboard 有两个 Completed 处理程序,第一个首先执行,因此使用第一个参数导航到 Page2。

不要每次都添加Completed 处理程序,只需执行一次,并将 URL 存储在属性中:

在您的 XAML 中:

<Storyboard x:Key="Animation2" Completed="Storyboard_Completed">
    <!-- whatever-->
</Storyboard>    

然后在你的 C# 代码中:

protected string Uri { get; set; }

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    animation1.Stop();
    animation2.Stop();
    animation1.Begin();
}

private void button1_Click(object sender, RoutedEventArgs e)
{          
    this.Uri = "/fooApp;component/Page2.xaml?id=1";
    animation2.Begin();                       
}

private void button2_Click(object sender, RoutedEventArgs e)
{
    this.Uri = "/fooApp;component/Page2.xaml?id=2";
    animation2.Begin();          
}

private void button3_Click(object sender, RoutedEventArgs e)
{
    this.Uri = "/fooApp;component/Page2.xaml?id=3";
    animation2.Begin();              
}

private void Storyboard_Completed(object sender, EventArgs e)
{
    this.NavigationService.Navigate(new Uri(this.Uri, UriKind.Relative));      
}

奖励:

删除事件处理程序

如果要删除事件处理程序,只需使用 -= 运算符。但是你不能使用 lambda,你必须使用“经典”方法:

// Good
this.animation2.Completed -= Storyboard_Completed;

// Wrong
this.animation2.Completed -= (sender, e) => NavigationService.Navigate(new Uri("RandomText_JustWantCompletedEventToBeHit", UriKind.Relative));    

替代实现

如果您的所有按钮都是触发动画并重定向到 Page2,那么您可以通过控件的Tag 属性以更通用的方式处理它。 Tag 属性允许你存储任何你想识别控件的对象。

XAML:

<Button Click="Button_Click" Content="Button 1" Tag="1" />
<Button Click="Button_Click" Content="Button 2" Tag="2" />
<Button Click="Button_Click" Content="Button 3" Tag="3" />

C#:

private void Button_Click(object sender, RoutedEventArgs e)
{
     var element = (FrameworkElement)sender;
     this.Url = "/fooApp;component/Page2.xaml?id=" + element.Tag.ToString();

     animation2.Begin();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    相关资源
    最近更新 更多