旋转控件显示一个Pivot但在另一个中注册了水龙头

时间:2014-02-03 10:35:13

标签: c# xaml windows-phone-8

我有一个todolist应用,在ListBox控件中的单独PivotItems内有几个Pivot控件。如果我导航到另一个页面,并使用后退按钮返回,则显示的Pivot无响应。但是,它上面的活动(滚动,点击等)似乎会影响 next Pivot结束,即selectedIndex + 1;

这听起来非常像Pivot控件中的错误,但也许我做错了什么?这是我的枢轴控制的代码。

[code updated, see below]

我不认为我导航到的页面代码很重要,因为后退按钮会发生这种行为

其他一些重要信息:

  • 第一个 PivotItem(索引0)上,错误不会
  • last PivotItem上,出现了另一个问题。导航离开 last 列表并通过后退按钮返回显示空列表
  • 在所有情况下,通过向左或向右滑动列表然后返回来解决问题。

编辑:

我错误的是页面代码不重要。我在OnNavigatedTo方法而不是MainPage方法中绑定。 Romasz提供了一个完美的样本。我通过更改三个部分以匹配我自己的非工作代码来打破它

  1. 将页面设置为继承自INotifyPropertyChanged(因为我使用NotifyPropertyChanged
  2. 将数据绑定代码移至OnNavigatedTo方法
  3. 在代码隐藏
  4. 中设置ItemsSource的{​​{1}}

    通过这三项更改,样本无效。这是代码。

    MainPage.xaml中

    PivotControl

    MainPage.xaml.cs中

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid x:Name="ContentPanel" Margin="12,0,12,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="9*"/>
            </Grid.RowDefinitions>
            <Button x:Name="myButton" VerticalAlignment="Top" 
                 Content="Go to different Page!" Grid.Row="0"/>
            <controls:Pivot x:Name="PivotControl" Grid.Row="1" 
                 ItemsSource="{Binding Lists}">
                <controls:Pivot.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}"/>
                    </DataTemplate>
                </controls:Pivot.HeaderTemplate>
                <controls:Pivot.ItemTemplate>
                    <DataTemplate>
                        <ListBox ItemsSource="{Binding Items}" 
                HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" 
                Margin="24,0,0,0" Height="Auto" VerticalAlignment="Stretch">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <CheckBox></CheckBox>
                                        <TextBlock Text="{Binding Title}"/>
                                    </StackPanel>                                    
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                    </DataTemplate>
                </controls:Pivot.ItemTemplate>
            </controls:Pivot>
        </Grid>
    </Grid>
    

    完整项目:https://dl.dropboxusercontent.com/u/568631/PivotProblem_2.zip

    此代码与我所遇到的问题非常相似。如果您移动到第二个或第三个列表,单击“转到另一个页面”按钮,然后点击后退按钮,枢轴移动到“第一个”列表并将其显示为空。向导和向后导航会重置列表。

    如果我更改了三个差异中的任何一个 - 删除了public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged { public class myItems { public string Title { get; set; } } public class myList { public string Name { get; set; } private List<myItems> items = new List<myItems>(); public List<myItems> Items { get { return items; } set { items = value; } } } private ObservableCollection<myList> _Lists; public ObservableCollection<myList> Lists { get { return _Lists; } set { if (_Lists != value) { _Lists = value; NotifyPropertyChanged("Lists"); } } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } // Constructor public MainPage() { InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); Lists = new ObservableCollection<myList>(); myList list1 = new myList() { Name = "First" }; for (int i = 0; i < 100; i++) list1.Items.Add(new myItems() { Title = (i + 1).ToString() }); myList list2 = new myList() { Name = "Second" }; for (int i = 100; i < 200; i++) list2.Items.Add(new myItems() { Title = (i + 1).ToString() }); myList list3 = new myList() { Name = "Third" }; for (int i = 200; i < 300; i++) list3.Items.Add(new myItems() { Title = (i + 1).ToString() }); myList list4 = new myList() { Name = "Fourth" }; for (int i = 300; i < 400; i++) list4.Items.Add(new myItems() { Title = (i + 1).ToString() }); Lists.Add(list1); Lists.Add(list2); Lists.Add(list3); Lists.Add(list4); myButton.Click += first_Click; this.DataContext = this; } private void first_Click(object sender, RoutedEventArgs e) { NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.RelativeOrAbsolute)); } } 的继承,将绑定代码移动到MainPage或在代码隐藏中设置INotifyPropertyChanged - 应用程序再次按预期工作。这已经成为一个学术问题(由于缺乏一个更好的术语),因为它不再影响我的应用程序,但我仍然不知道为什么这三个因素结合起来导致奇怪的ItemsSource行为

    要重新进行迭代,更改上述任何一个因素都会消除问题 - 那么是什么导致了这个问题呢?

2 个答案:

答案 0 :(得分:0)

根据您的描述,我构建了a simple App。有一个包含4个项目的Pivot,每个项目都有一个带有texblocks的列表。在Pivot上方有一个导航到下一页的按钮。

我已经测试了这样的情况:

  • 在First PivotItem中滚动列表,选择项目,导航到Page,Back =&gt; Pivot和List重新响应
  • 将PivotItem更改为第二个,向下滚动列表,选择项目,导航到Page,Back =&gt; Pivot和List重新响应
  • 在First PivotItem中向下滚动列表,将PivotItem更改为第二,向下滚动列表,选择项目,将PivotItem更改为第三,向下滚动列表,选择项目,导航到Page,Back =&gt; Pivot和List重新响应

我无法重现你的问题(模拟器WP8)。你能检查一下吗?我错过了什么吗?

编辑 - 评论后

事实上,在您提供的代码中存在这样的问题。现在我已经设法发现问题主要与清除列表(或创建新列表)有关。我还设法找到一个小解决方法(the complete code):

如果我删除列表中的项目(第一个除外)(在OnNavigatedTo中)和添加新项目后删除第一个项目,那么一切似乎都可以正常工作:

while (Lists.Count > 1)
   Lists.RemoveAt(1);
// add new items
Lists.RemoveAt(0); // watch out for the first run of OnNavigatedTo - there is a need here for if statement or something

我知道它没有回答问题发生的原因,但也许它会有所帮助或提供一个很好的线索。当我有更多时间时,我也会尝试使用它。

我还假设您每次NavigateTo都需要重新创建列表。

答案 1 :(得分:0)

根据您的代码,您可以轻松地执行某些操作,只需标记

即可
    bool IsDataLoaded = false; //flag

    public MainPage()
    {
        InitializeComponent();

    }
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {

        base.OnNavigatedTo(e);

        if (!IsDataLoaded)
        {
            Lists = new ObservableCollection<myList>();

            myList list1 = new myList() { Name = "First" };
            for (int i = 0; i < 100; i++)
                list1.Items.Add(new myItems() { Title = (i + 1).ToString() });

            myList list2 = new myList() { Name = "Second" };
            for (int i = 100; i < 200; i++)
                list2.Items.Add(new myItems() { Title = (i + 1).ToString() });

            myList list3 = new myList() { Name = "Third" };
            for (int i = 200; i < 300; i++)
                list3.Items.Add(new myItems() { Title = (i + 1).ToString() });

            myList list4 = new myList() { Name = "Fourth" };
            for (int i = 300; i < 400; i++)
                list4.Items.Add(new myItems() { Title = (i + 1).ToString() });

            Lists.Add(list1);
            Lists.Add(list2);
            Lists.Add(list3);
            Lists.Add(list4);

            myButton.Click += first_Click;
            this.DataContext = this;
            IsDataLoaded = true;
        }

    }

每次页面变为活动时,都会调用OnNavigatedTo方法。这是你的问题(: