2017-03-09 11 views
1

私はVS2015コミュニティのUWPを今学んでいて、ComboBoxに関して1つのセクションに問題があり、本当に助けを得ることができます。ComboBoxのSelectedIndexがデータ変更の最初の項目に

私は聖書のアプリを書いていて、翻訳、本、章のために3つのコンボボックスを持っています。ブックのドロップダウンを変更すると、章が1に変わるはずです。少なくとも、章の前と後ろのボタンをクリックするまでは、今すぐ基本をカバーするだけです。私が翻訳を変更するとき、NIVからKJVに言えば、その翻訳で現在選択されている書籍/チャプターに変更する必要があります。

私はXMLからテキストをプリロードし、それらをdataLoaderというオブジェクトにロードしました。私は、下のコードでLINQ経由で選択を行っています。

だから、今、私が何か言う:場合は、最初に翻訳の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; 
    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であるブックの範囲外になるように、まず翻訳を実行します。

適切なイベントをトリガするために選択したインデックスを変更したいが、それが現在の状態では動作しないことがわかる。また、コードはかなり厄介です、私はバインディングを少し見始めたが、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; 
    } 
} 

これで1つのしゃっくりがあります - あなたはそれが原因-1に、前処理しないように、手動でDataLoader_Completedのエンドでbookchanged ()を起動する必要がありますが。

+0

それ以外のイベントは無視されてしまったので、私はそれがドロップダウンに依存しますので、空のドロップダウンまたはテキストビューが更新されませんでしただろう、私はそれが働いて取得することよりもさらにをしなければならなかったが判明。SelectedIndexの設定をトリガーするとすぐにイベントが更新されるため、起動しなくても問題が発生しますが、その解説で説明する「パラドックス」に入ります。 –

0

私が作成したプロパティへのバインディングを使用すると、より良い解決策が得られた可能性がありますが、改善についてのいくつかのフィードバックは常に設計の観点から役立ちます。私が本質的に行ったことは、falseに設定するとSelectedIndex変更イベントを処理しないが、基になるデータソースを更新し、SelectedIndexをオンザフライで変更できるUpdateChapterText Booleanプロパティを作成したことです。それ以外の場合は、複数のイベントが発生して基礎となるデータソースが更新される可能性があります。チャプター・テキスト・ビューでは、選択された索引の翻訳とブックの両方に依存しているため、デフォルト・ビヘイビアではイベント処理の前にどちらか一方のみを設定することができ、少なくとも解決不可能になるため私が見つけたイベント処理をオフにしない限り、今は考えています。

/// <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(); 
     } 
    } 
関連する問題