2017-03-09 63 views
1

我現在正在學習VS2015社區中的UWP,並且在關於ComboBox的一節中遇到問題,並且確實可以使用一些幫助。ComboBox上的SelectedIndex到數據更改的第一項

我正在寫聖經應用程序,並有3個組合框用於翻譯,書本和章節。當我更改Book下拉菜單時,它應該將章節更改爲1.至少在爲章節制作前後按鈕之前,現在只是介紹基本知識。當我改變翻譯時,我們可以說從NIV到KJV,它應該改變爲當前選擇的那個翻譯中的書/章。

我已經預裝了來自XML的文本並將它們加載到一個名爲dataLoader的對象中。我在下面的代碼中通過LINQ進行選擇。

所以現在我這樣說:

private void DataLoader_Completed(object sender, EventArgs e) 
{ 
    dataLoaded = true; 
    cmb_Translation.ItemsSource = from t in dataLoader.Translations select new { t.TranslationShortName }; 
    cmb_Book.ItemsSource = from b in dataLoader.Translations[0].Books select new { b.BookName }; 
    cmb_Chapter.ItemsSource = from c in dataLoader.Translations[0].Books[0].Chapters select new { c.Index }; 
    cmb_Book.SelectedIndex = 0; 
    cmb_Translation.SelectedIndex = 0; 
    cmb_Chapter.SelectedIndex = 0; 
} 

private void translationChanged() 
{ 
    chapterChanged(); 
} 

private void bookChanged() 
{ 
    cmb_Chapter.ItemsSource = from c in dataLoader.Translations[cmb_Translation.SelectedIndex].Books[cmb_Book.SelectedIndex].Chapters select new { c.Index }; 
    cmb_Chapter.SelectedIndex = 0; 
} 

private void chapterChanged() 
{ 
    textBlock_Verses.Text = dataLoader.Translations[cmb_Translation.SelectedIndex].Books[cmb_Book.SelectedIndex].Chapters[cmb_Chapter.SelectedIndex].TextLineSeparated; 
} 

private void cmb_Translation_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    translationChanged(); 
} 

private void cmb_Book_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    bookChanged(); 
} 

private void cmb_Chapter_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    chapterChanged(); 
} 

遇到錯誤,雖然在該指數超出範圍,因爲翻譯的起初的SelectedIndex爲-1第一次運行時回來,如果我首先運行翻譯,它會讓我在SelectedIndex爲-1的書上超出範圍。

我希望選定的索引更改觸發正確的事件,但正如你所看到的那樣,現在它不會如何工作。此外,代碼非常混亂,我已經開始考慮一下Binding,但是有很多障礙想要解決如何綁定到返回LINQ結果的屬性。我不知道如何向前邁進,絕對感謝我能得到的任何幫助。

回答

1

組合框可以沒有選擇 - 選擇產品這是它是如何初始化的,所以,如果你設置SelectedInexes所有人都(這意味着SelectedIndex == -1):

private void DataLoader_Completed(object sender, EventArgs e) 
{ 
    dataLoaded = true; 
    cmb_Translation.ItemsSource = from t in dataLoader.Translations select new { t.TranslationShortName }; 
    cmb_Book.ItemsSource = from b in dataLoader.Translations[0].Books select new { b.BookName }; 
    cmb_Chapter.ItemsSource = from c in dataLoader.Translations[0].Books[0].Chapters select new { c.Index }; 
    cmb_Book.SelectedIndex = 0; // <- you set here selected index for book 
           // which fires bookchanged even right away 
           // In that event cmb_Translation.SelectedIndex 
           // is still -1 which will surely throw exception 
    cmb_Translation.SelectedIndex = 0; 
    cmb_Chapter.SelectedIndex = 0; 
} 

你如果在使用它們之前正確設置了值,可能應該進行一些檢查。還有想當有沒有選擇狀態時有機會。

private void bookChanged() 
{ 
    if (cmb_Translation.SelectedIndex >= 0) 
    { 
     cmb_Chapter.ItemsSource = from c in dataLoader.Translations[cmb_Translation.SelectedIndex].Books[cmb_Book.SelectedIndex].Chapters select new { c.Index }; 
     cmb_Chapter.SelectedIndex = 0; 
    } 
} 

有一個打嗝這個 - 你將不得不在DataLoader_Completed內切手動啓動bookchanged(),因爲它不會前過程中,由於-1

+0

原來我不得不做更多的工作,否則事件被忽略,所以我會有空下拉或文本視圖不會得到更新,因爲它取決於下拉菜單。只要你觸發設置SelectedIndex,它就會更新事件,所以如果它根本沒有觸發,你就會遇到麻煩,但是你遇到了一個「悖論」,我會在答案中解釋它。 –

0

這是我找到的解決方案,儘管我認爲使用綁定到我創建的屬性也許可以實現更好的解決方案,但從設計的角度來看,有關改進的一些反饋總是有幫助的。我做的基本上是創建一個UpdateChapterText布爾屬性,當設置爲false時不會處理我的SelectedIndex更改事件,但仍然允許我更新基礎數據源並即時更改SelectedIndex,這樣我就可以在一個事件中處理事件去吧,否則它可能會觸發多個事件來更新底層數據源。我需要能夠這樣做,因爲對於章節文本視圖而言,它依賴於翻譯和書籍選擇索引來設置,但默認行爲只允許在事件處理之前設置其中一個或另一個,這至少無法解決我認爲現在除非你關閉我發現的事件處理。

/// <summary> 
    /// This is a helper property for setting the Translation SelectedIndex 
    /// </summary> 
    private int TranslationIndex 
    { 
     get 
     { 
      return cmb_Translation.SelectedIndex; 
     } 
     set 
     { 
      cmb_Translation.SelectedIndex = value; 
     } 
    } 

    /// <summary> 
    /// This is a helper property for setting the Book SelectedIndex 
    /// </summary> 
    private int BookIndex 
    { 
     get 
     { 
      return cmb_Book.SelectedIndex; 
     } 
     set 
     { 
      cmb_Book.SelectedIndex = value; 
     } 
    } 

    /// <summary> 
    /// This is a helper property for setting the Chapter SelectedIndex 
    /// </summary> 
    private int ChapterIndex 
    { 
     get 
     { 
      return cmb_Chapter.SelectedIndex; 
     } 
     set 
     { 
      cmb_Chapter.SelectedIndex = value; 
     } 
    } 

    /// <summary> 
    /// Retrieves the currently selected Chapter listing 
    /// </summary> 
    public IEnumerable<ChapterIndex> CurrentChapters 
    { 
     get 
     { 
      return from c in dataLoader.Translations[TranslationIndex].Books[BookIndex].Chapters select new ChapterIndex { Index = c.Index }; 
     } 
    } 

    /// <summary> 
    /// Retrieves Genesis in the first loaded translation 
    /// </summary> 
    public IEnumerable<ChapterIndex> Genesis 
    { 
     get 
     { 
      return from c in dataLoader.Translations[0].Books[0].Chapters select new ChapterIndex { Index = c.Index }; 
     } 
    } 

    public IEnumerable<BookNames> CurrentBooks 
    { 
     get 
     { 
      return from b in dataLoader.Translations[TranslationIndex].Books select new BookNames { BookName = b.BookName }; 
     } 
    } 

    /// <summary> 
    /// Allows events to process on ComboBoxes and Back/Forward Buttons 
    /// to change Chapters, you usually don't want to do this lots of 
    /// times in one second if changing the Translation/Book/Chapter 
    /// all at one time so you may set it to false first, update your 
    /// variables, and then set it back to true so updating events will 
    /// process correctly. 
    /// </summary> 
    public bool UpdateChapterText { get; set; } 

    /// <summary> 
    /// The DataLoader object loads up the various Bible translation texts 
    /// </summary> 
    TheBible.Model.DataLoader.DataLoader dataLoader; 

    public MainPage() 
    { 
     this.InitializeComponent(); 
     dataLoader = new Model.DataLoader.DataLoader(); 
     dataLoader.Completed += DataLoader_Completed; 
     ApplicationView.GetForCurrentView().TryEnterFullScreenMode(); 
    } 

    private void DataLoader_Completed(object sender, EventArgs e) 
    { 
     UpdateChapterText = false; 
     cmb_Translation.ItemsSource = from t in dataLoader.Translations select new { t.TranslationShortName }; 
     cmb_Book.ItemsSource = from b in dataLoader.Translations[0].Books select new { b.BookName }; 
     cmb_Chapter.ItemsSource = Genesis; 
     cmb_Translation.SelectedIndex = 0; 
     cmb_Book.SelectedIndex = 0; 
     UpdateChapterText = true; 
     cmb_Chapter.SelectedIndex = 0; 
    } 

    private void translationChanged() 
    { 
     chapterChanged(); 
    } 

    private void bookChanged() 
    { 
     UpdateChapterText = false; 
     cmb_Chapter.ItemsSource = CurrentChapters; 
     UpdateChapterText = true; 
     cmb_Chapter.SelectedIndex = 0; 
    } 

    private void chapterChanged() 
    { 
     textBlock_Verses.Text = dataLoader.Translations[TranslationIndex].Books[BookIndex].Chapters[ChapterIndex].TextLineSeparated; 
    } 

    private void decrementChapter() 
    { 
     UpdateChapterText = false; 
     if (this.cmb_Chapter.SelectedIndex == 0) 
     { 
      if (this.cmb_Book.SelectedIndex > 0) 
      { 
       this.cmb_Book.SelectedIndex--; 
       UpdateChapterText = true; 
       this.cmb_Chapter.SelectedIndex = CurrentChapters.Count() - 1; 
      } 
     } 
     else 
     { 
      UpdateChapterText = true; 
      this.cmb_Chapter.SelectedIndex--; 
     } 
     UpdateChapterText = true; 
    } 

    private void incrementChapter() 
    { 
     UpdateChapterText = false; 
     if (this.cmb_Chapter.SelectedIndex == this.cmb_Chapter.Items.Count - 1) 
     { 
      if (this.cmb_Book.SelectedIndex < this.cmb_Book.Items.Count - 1) 
      { 
       this.cmb_Book.SelectedIndex++; 
       UpdateChapterText = true; 
       this.cmb_Chapter.SelectedIndex = 0; 
      } 
     } 
     else 
     { 
      UpdateChapterText = true; 
      this.cmb_Chapter.SelectedIndex++; 
     } 
     UpdateChapterText = true; 
    } 

    private void cmb_Translation_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (UpdateChapterText) 
      translationChanged(); 
    } 

    private void cmb_Book_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (UpdateChapterText) 
      bookChanged(); 
    } 

    private void cmb_Chapter_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (UpdateChapterText) 
      chapterChanged(); 
    } 

    private void btn_Forward_Click(object sender, RoutedEventArgs e) 
    { 
     incrementChapter(); 
    } 

    private void btn_Back_Click(object sender, RoutedEventArgs e) 
    { 
     decrementChapter(); 
    } 

    private void btn_FullScreen_Click(object sender, RoutedEventArgs e) 
    { 
     var view = ApplicationView.GetForCurrentView(); 
     if (view.IsFullScreenMode) 
     { 
      sym_FullScreen.Symbol = Symbol.FullScreen; 
      view.ExitFullScreenMode(); 
     } 
     else 
     { 
      sym_FullScreen.Symbol = Symbol.BackToWindow; 
      view.TryEnterFullScreenMode(); 
     } 
    } 
相關問題