Silverlight:当我调用 NavigationService.Navigate 时布局发生变化

发布于 2024-10-09 18:19:30 字数 6306 浏览 0 评论 0原文

这是一个非常奇怪的错误。我不知道为什么会发生这种情况。我知道将其发布在这里有点不太可能,但我没有其他想法。

我有两个充当菜单的 ListBox

                <ListBox Margin="56,8,15,0" FontSize="64"
                         ItemsSource="{Binding FavoriteSections}"
                         SelectionChanged="MenuList_SelectionChanged">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <toolkit:ContextMenuService.ContextMenu>
                                    <toolkit:ContextMenu>
                                        <toolkit:MenuItem Header="Remove" Click="FavoritesContextMenuItem_Click" />
                                    </toolkit:ContextMenu>
                                </toolkit:ContextMenuService.ContextMenu>

                                <TextBlock Text="{Binding DisplayName}" />
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>


                <ListBox x:Name="sectionList" Margin="56,8,15,0" FontSize="64" 
                         SelectionChanged="MenuList_SelectionChanged"
                         ItemsSource="{Binding SectionViewModels}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <toolkit:ContextMenuService.ContextMenu>
                                    <toolkit:ContextMenu>
                                        <toolkit:MenuItem Header="Add to favorites" Click="SectionContextMenuItem_Click" />
                                    </toolkit:ContextMenu>
                                </toolkit:ContextMenuService.ContextMenu>
                                <TextBlock Text="{Binding DisplayName}" />
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

该错误存在于他们两个身上。

当任一菜单上的选择发生更改时,都会调用此方法:

    void MenuList_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems.Count == 0)
        {
            return;
        }

        Uri page = null;
        object selected = e.AddedItems[0];
        if (selected is NavigableItem)
        {
            NavigableItem selectedItem = (NavigableItem)selected;
            page = selectedItem.Page;
        }
        else if (selected is SectionViewModel)
        {
            SectionViewModel selectedVM = (SectionViewModel)selected;
            page = selectedVM.Section.Page;
        }

        Debug.Assert(page != null, "What is the type of `selected`?");

        // if I comment out this line, the problem goes away:
        NavigationService.Navigate(page);

        ListBox selectedBox = (ListBox)sender;
        selectedBox.SelectedIndex = -1;
    }

如果我注释掉 NavigationService.Navigate() 行,问题就会消失。如果我用不同的 URI 替换该行,问题仍然存在。

大约 70% 的情况下,当我单击菜单项时,内容会跳遍整个页面。 (剩下的 30%,没有 bug 发生。)它发生得太快,无法看出到底发生了什么,但不同的 UI 元素相互重叠。

仅当我在应用程序的生命周期中第一次单击这些菜单中的某些内容时,才会发生这种情况。如果我点击“返回”然后再次选择菜单项,则不会出现该问题。

这里可能发生什么?我真的不知道。代码隐藏没有 OnNavigateFrom 方法,所以我认为这不是问题。

我正在使用 Silverlight for Windows Phone 7

更新:奇怪的是,我似乎无法在调试器中重现这一点 - 只有在部署应用程序并在未附加的模拟器中运行它之后。 ???

更新 2:当从按钮的 Click 事件处理程序调用 NavigationService.Navigate() 时也会出现该错误:

<Button Content="Foo" Click="Button_Click" Grid.Row="0"/>

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Views/sections.xaml?section=43", UriKind.Relative));
        }

看起来像bug 与导航有关,而不是用于触发调用的 UI 元素。

更新3:更多奇怪的事情。连接调试器时仍然无法重现应用程序。如果我使加载进度条始终折叠,错误就会消失:

                <ProgressBar x:Name="LoadingProgressBar"
                 IsIndeterminate="True"
                 Visibility="Collapsed"
                 Style="{StaticResource PerformanceProgressBar}"
                 VerticalAlignment="Top"/>

或者,在代码隐藏中注释掉这一行会使错误消失:

LoadingProgressBar.Visibility = Visibility.Collapsed;

我真的不明白这里发生了什么。当页面被导航时,该行代码不会被执行。

下面是混乱的控件的完整 XAML:

                    <ProgressBar x:Name="LoadingProgressBar"
                     IsIndeterminate="True"
                     Visibility="Collapsed"
                     Style="{StaticResource PerformanceProgressBar}"
                     VerticalAlignment="Top"/>

                <TextBlock x:Name="DownloadFailed"
                         Visibility="Collapsed"
                         Style="{StaticResource disabledText}"
                         Margin="56,8,8,-8" >
                    FooBar.com could not be reached. Do you have a network connection?
                </TextBlock>

                <ListBox x:Name="sectionList" Margin="56,8,15,0" FontSize="64" 
                         SelectionChanged="MenuList_SelectionChanged"
                         ItemsSource="{Binding SectionViewModels}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <toolkit:ContextMenuService.ContextMenu>
                                    <toolkit:ContextMenu>
                                        <toolkit:MenuItem Header="Add to favorites" Click="SectionContextMenuItem_Click" />
                                    </toolkit:ContextMenu>
                                </toolkit:ContextMenuService.ContextMenu>
                                <TextBlock Text="{Binding DisplayName}" />
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

            </Grid>
        </controls:PivotItem>

This is a really weird bug. I have no idea why it could be happening. I know that posting it here is a bit of a long-shot, but I'm out of other ideas.

I have two ListBoxs that act as menus.

                <ListBox Margin="56,8,15,0" FontSize="64"
                         ItemsSource="{Binding FavoriteSections}"
                         SelectionChanged="MenuList_SelectionChanged">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <toolkit:ContextMenuService.ContextMenu>
                                    <toolkit:ContextMenu>
                                        <toolkit:MenuItem Header="Remove" Click="FavoritesContextMenuItem_Click" />
                                    </toolkit:ContextMenu>
                                </toolkit:ContextMenuService.ContextMenu>

                                <TextBlock Text="{Binding DisplayName}" />
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>


                <ListBox x:Name="sectionList" Margin="56,8,15,0" FontSize="64" 
                         SelectionChanged="MenuList_SelectionChanged"
                         ItemsSource="{Binding SectionViewModels}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <toolkit:ContextMenuService.ContextMenu>
                                    <toolkit:ContextMenu>
                                        <toolkit:MenuItem Header="Add to favorites" Click="SectionContextMenuItem_Click" />
                                    </toolkit:ContextMenu>
                                </toolkit:ContextMenuService.ContextMenu>
                                <TextBlock Text="{Binding DisplayName}" />
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

The bug exists across both of them.

When the selection changes on either menu, this method is called:

    void MenuList_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems.Count == 0)
        {
            return;
        }

        Uri page = null;
        object selected = e.AddedItems[0];
        if (selected is NavigableItem)
        {
            NavigableItem selectedItem = (NavigableItem)selected;
            page = selectedItem.Page;
        }
        else if (selected is SectionViewModel)
        {
            SectionViewModel selectedVM = (SectionViewModel)selected;
            page = selectedVM.Section.Page;
        }

        Debug.Assert(page != null, "What is the type of `selected`?");

        // if I comment out this line, the problem goes away:
        NavigationService.Navigate(page);

        ListBox selectedBox = (ListBox)sender;
        selectedBox.SelectedIndex = -1;
    }

If I comment out the NavigationService.Navigate() line, the problem goes away. If I replace the line with a different URI, the problem remains.

About 70% of the time, when I click on a menu item, the content jumps all over the page. (The remaining 30%, no bug occurs.) It happens too quickly to see what's really going on, but different UI elements overlap each other.

This only occurs the first time I click on something in those menus during the app's lifetime. If I hit "back" then select a menu item again, the problem will not occur.

What could be happening here? I really have no idea. The code-behind doesn't have a OnNavigatedFrom method, so I don't think it's a problem there.

I'm using Silverlight for Windows Phone 7

Update: Mysteriously, I can't seem to reproduce this in the debugger - only after deploying the app and running it in the emulator unattached. ???

Update 2: The bug appears when NavigationService.Navigate() is called from the Click event handler of a button, as well:

<Button Content="Foo" Click="Button_Click" Grid.Row="0"/>

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Views/sections.xaml?section=43", UriKind.Relative));
        }

Looks like the bug has to do with the navigation, not the UI element used to trigger the call.

Update 3: More weirdness. Still not able to reproduce the app while the debugger is attached. If I make the loading progress bar always collapsed, the bug disappears:

                <ProgressBar x:Name="LoadingProgressBar"
                 IsIndeterminate="True"
                 Visibility="Collapsed"
                 Style="{StaticResource PerformanceProgressBar}"
                 VerticalAlignment="Top"/>

Alternatively, commenting out this line in code-behind makes the bug disappear:

LoadingProgressBar.Visibility = Visibility.Collapsed;

I really don't understand what's going on here. That line of code is not executed when the page is navigated from.

Here is the full XAML of the control that's getting messed up:

                    <ProgressBar x:Name="LoadingProgressBar"
                     IsIndeterminate="True"
                     Visibility="Collapsed"
                     Style="{StaticResource PerformanceProgressBar}"
                     VerticalAlignment="Top"/>

                <TextBlock x:Name="DownloadFailed"
                         Visibility="Collapsed"
                         Style="{StaticResource disabledText}"
                         Margin="56,8,8,-8" >
                    FooBar.com could not be reached. Do you have a network connection?
                </TextBlock>

                <ListBox x:Name="sectionList" Margin="56,8,15,0" FontSize="64" 
                         SelectionChanged="MenuList_SelectionChanged"
                         ItemsSource="{Binding SectionViewModels}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <toolkit:ContextMenuService.ContextMenu>
                                    <toolkit:ContextMenu>
                                        <toolkit:MenuItem Header="Add to favorites" Click="SectionContextMenuItem_Click" />
                                    </toolkit:ContextMenu>
                                </toolkit:ContextMenuService.ContextMenu>
                                <TextBlock Text="{Binding DisplayName}" />
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

            </Grid>
        </controls:PivotItem>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暮年慕年 2024-10-16 18:19:30

问题在于您对不确定进度条的使用。它的所有动画都是在 UI 线程上完成的,而不是像通常的做法那样在合成器线程上完成。由于您已经在使用 Windows Phone Toolkit,因此您可以轻松地将 ProgressBar 替换为该工具包提供的 PerformanceProgressBar。这应该可以解决您的问题。

The problem lies in your usage of the Indeterminate ProgressBar. All its animations are done on the UI thread, and not the Compositor thread, as is the usual practise. Since you are already using the Windows Phone Toolkit, you can easily replace your ProgressBar with the PerformanceProgressBar offered by the toolkit. This should solve your problems.

森林迷了鹿 2024-10-16 18:19:30

在开始之前,我要说的是,我没有太多使用 Windows Phone 的经验,因此我的答案基于更通用的 WPF 知识,因此,如果我忽略了平台的具体情况,或者引用的功能并非如此,请原谅我。可用的。

一些诊断问题(抱歉,这不是直接答案):

首先,Navigate 似乎确实调用了大量布局更新。我还没有看到什么类型的容器包含您正在更新的页面,但值得一问的是,它是否也被破坏或只有菜单?

其次,您可以尝试明确指定您的 itemPanel 吗?您期望它们是 virtualizingStackPanels,但您可能会发现视觉层次结构中的某些父对象正在创建不同的继承场景。

您将这些放在网格中,这意味着要根据其内容调整大小,或者采用默认大小(正常 WPF 中为 100x100)或从其父级中获取大小,而无需知道您如何指定网格或网格的父级,很难了解它的行为。此外,网格会根据其子级的添加顺序自动对其子级进行 z 排序。你能确定是否只是lisboxes的布局被扰乱了,还是整个网格都被扰乱了?或者说,它比这个大吗?

如果您附加到列表框、网格或网格父级的layoutUpdated()事件,您应该能够查看引导您到达那里的堆栈跟踪 - 在我看来,您会发现layoutUpdated()触发的次数超过你会喜欢的。此外,您将能够在这些步骤中输出高度和宽度(当然是实际高度等),以便您可以看到这些更改何时发生。

我希望其中一些诊断步骤可以帮助您找到答案。

Before I begin, let me say that I don't have a lot of experience with Windows Phone, so my answers are based on more generic WPF knowledge, so forgive me if I'm overlooking specifics of the platform, or am referencing features not available.

Some diagnostic questions (sorry this isn't a direct answer):

Firstly, it does seem like Navigate is calling a lot of layoutUpdates. I haven't yet seen what type of container is containing the pages you're updating, but it is worth asking, is that also being disrupted or only the menus?

Secondly, could you try specifying your itemPanel explicitly? You're expecting them to be virtualizingStackPanels, but you may find that some parent object in your visual hierarchy is creating a different inheritance scenario.

You have these in a grid, which is meant to size to its content, or take the default size (100x100 in normal WPF) or take sizing from its parent, which without knowing how you've specified the grid, or the grid's parent, it's difficult to know its behaviour. Furthermore, Grids automatically z-order their children according to the order in which they were added. Can you determine whether it is just the layout of the lisboxes that is being disturbed, or whether it is the entire grid? Or, is it larger than that?

If you attach to the layoutUpdated() event of the listboxes, grid, or grid's parent, you should be able to look at the stacktraces that lead you there - it sounds to me that you'll find that layoutUpdated() is firing more than you'd like it to. Further, you'll be able to output the heights and widths (ActualHeight etcetera of course) during those steps so that you can see when exactly those changes happen.

I hope that some of these diagnostic steps might help you reach an answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文