在 WP10 的 Pivot 中设置并滚动到 ListBox 的 SelectedIndex

Set and Scroll to SelectedIndex of ListBox in Pivot in WP10

我正在尝试在 Pivot 中绑定 SelectedIndex of ListBox。 Headers,项目绑定正确,但是,ListBox SelectedIndex 无法正常工作。

XAML

<Page.DataContext>
        <local:ChapterMenuViewModel/>
    </Page.DataContext>
<Pivot x:Name="pvMain" TitleTemplate="{StaticResource PivotTitleTemplate}"
  HeaderTemplate="{StaticResource PivotHeaderTemplate}"
  ItemsSource="{Binding ChapterMenuHeader}" SelectionChanged="pvMain_SelectionChanged">
  <Pivot.ItemTemplate>
    <DataTemplate>
      <Grid Grid.Row="1" Grid.Column="0">
      <ListBox FlowDirection="RightToLeft" FontFamily="./Fonts/ScheherazadeRegOT.ttf#Scheherazade" 
       x:Name="lsbChapter" ItemTemplate="{StaticResource ChapterItemTemplate}"
       SelectedIndex="{Binding SelectedChapterIndex}"
       ItemsSource="{Binding Chapters}">
      </ListBox>
    </Grid>
  </DataTemplate>
 </Pivot.ItemTemplate>
</Pivot>

MVVM

public class ChapterMenuViewModel : INotifyPropertyChanged
    {
        ObservableCollection<ChapterMenusHeader> _chapterMenuHeader;
        DataSource ds = null;
        public ChapterMenuViewModel()
        {
            ChapterMenuHeader = new ObservableCollection<ChapterMenusHeader>();
            ds = new DataSource();

            List<JuzDetail> allJuz = DataSource.GetAllJuz;
            ChapterMenuHeader.Add(new ChapterMenusHeader() { Header = "chapter", Chapters = DataSource.GetAllChapter, Juzs = allJuz });
            ChapterMenuHeader.Add(new ChapterMenusHeader() { Header = "location", Chapters = DataSource.GetAllChapterSortedByChapterType, Juzs = allJuz });
            ChapterMenuHeader.Add(new ChapterMenusHeader() { Header = "order", Chapters = DataSource.GetAllChapterSortedByOrder, Juzs = allJuz });
            ChapterMenuHeader.Add(new ChapterMenusHeader() { Header = "size", Chapters = DataSource.GetAllChapterSortedBySize, Juzs = allJuz });
            ChapterMenuHeader.Add(new ChapterMenusHeader() { Header = "arabic name", Chapters = DataSource.GetAllChapterSortedByArabicAlphabet, Juzs = allJuz });
            ChapterMenuHeader.Add(new ChapterMenusHeader() { Header = "english name", Chapters = DataSource.GetAllChapterSortedByEnglishAlphabet, Juzs = allJuz });
        }
        public ObservableCollection<ChapterMenusHeader> ChapterMenuHeader
        {
            get { return _chapterMenuHeader; }
            set
            {
                if (_chapterMenuHeader != value)
                {
                    _chapterMenuHeader = value;
                    OnPropertyChanged("ChapterMenuHeader");
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public class ChapterMenusHeader : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            public void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }

            public ChapterMenusHeader()
            {
                SelectedChapterIndex = App.Recent.ChapterID;
            }
            string _header;
            public string Header
            {
                get { return _header; }
                set
                {
                    if (_header != value)
                    {
                        _header = value;
                        OnPropertyChanged("Header");
                    }
                }
            }

            List<Chapter> _allChapters;
            public List<Chapter> Chapters
            {
                get { return _allChapters; }
                set
                {
                    if (_allChapters != value)
                    {
                        _allChapters = value;
                        OnPropertyChanged("Chapters");
                    }
                }
            }

            int _selectedChapterIndex;
            public int SelectedChapterIndex
            {
                get { return _selectedChapterIndex; }
                set
                {
                    _selectedChapterIndex = value;
                    OnPropertyChanged("SelectedChapterIndex");
                }
            }
            List<JuzDetail> allJuz;
            public List<JuzDetail> Juzs
            {
                get { return allJuz; }
                set
                {
                    if (allJuz != value)
                    {
                        allJuz = value;
                        OnPropertyChanged("Juzs");
                    }
                }
            }
        }

滚动部分

private void lsbChapter_SelectionChanged(object sender, SelectionChangedEventArgs e)
 {
   ListBox lsb = sender as ListBox;
   if (lsb.SelectedIndex != -1)
      scrollIntoSelectedItem(lsb, lsb.SelectedIndex);
 }

void scrollIntoSelectedItem(ListBox lsb, int index)
{
   lsb.SelectionChanged -= lsbChapter_SelectionChanged;
   lsb.SelectedIndex = lsb.Items.Count - 1;
   lsb.UpdateLayout();
   lsb.ScrollIntoView(lsb.SelectedIndex);

   lsb.SelectedIndex = index;
   lsb.UpdateLayout();
   lsb.ScrollIntoView(index);

   lsb.SelectionChanged += lsbChapter_SelectionChanged;
}

这只是 ViewModel class 的一部分,我在其中绑定了 ListBoxSelectedIndexListBox 项目绑定正确,但是,SelectedIndex 不工作。 如何在Pivot中设置和滚动ListBoxSelectedIndex

谢谢!

原来问题出在这一行 -

SelectedIndex="{Binding SelectedChapterIndex}" ItemsSource="{Binding Chapters}"

您需要将 ItemsSource 绑定移到 SelectedIndex 前面 -

ItemsSource="{Binding Chapters}" SelectedIndex="{Binding SelectedChapterIndex}"

原因?我怀疑这是因为两个值的实例化顺序。当SelectedIndex放在xaml中的ItemsSource前面并在构造函数中赋值时,ItemsSource仍然是null,所以什么都不会被选中。

现在,要滚动到特定项目,您需要调用 ListBox 上的 ScrollIntoView 方法。在你的情况下,它应该是

lsbChapter.ScrollIntoView(Chapters[SelectedChapterIndex]);