ComboBox上的SelectedIndex到数据更改的第一项

时间:2017-03-09 23:44:16

标签: c# uwp

我现在正在VS2015社区学习UWP,并且在部分ComboBox方面遇到问题,可以真正使用一些帮助。

我正在写一本圣经应用程序,并有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结果的属性。我不确定如何继续前进,并且非常感谢我能得到的任何帮助。

2 个答案:

答案 0 :(得分:1)

Combobox没有选择 - 所选项目是 null ,这是它的初始化方式,因此在设置 SelectedInexes 之前,所有 null (这意味着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的endo启动 bookchanged(),因为-1之前它不会处理}。

答案 1 :(得分:0)

这是我所遇到的解决方案,虽然我认为可能使用Binding到我创建的属性可以实现更好的解决方案,但从设计角度来看,一些改进反馈总是有用的。我本质上做的是创建一个UpdateChapterText布尔属性,当设置为false时不会处理我的SelectedIndex更改事件,但仍然允许我更新底层数据源并动态更改SelectedIndex,这样我就可以处理一个事件go,否则可能会触发多个事件来更新底层数据源。我需要能够这样做,因为对于章节文本视图,它依赖于要设置的翻译和书籍选择索引,但默认行为只允许在事件处理之前设置一个或另一个,这至少变得无法解决我想现在除非你关闭我发现的事件处理。

h <- hash( keys=letters, values=1:26 )
h <- hash( letters, 1:26 )
h$a
# [1] 1
h$foo <- "bar"
h[ "foo" ]
# <hash> containing 1 key-value pair(s).
#   foo : bar
h[[ "foo" ]]
# [1] "bar"