设置ComboBox.SelectedIndex时为什么会出现异常?

时间:2017-04-24 18:04:22

标签: xaml data-binding uwp winrt-xaml

我正在尝试了解绑定和XAML。我有一个非常简单的例子,我将一个字符串数组绑定到XAML中定义的组合框。我还想设置所选索引。

我得到一个例外:

  

价值不在预期范围内。

使用 SelectedIndex 属性。

这是我用于UWP应用程序的XAML。

<StackPanel Background="{ThemeResource applicationPageBackgroundThemeBrush}">
    <ComboBox Name="BrowserCombo" ItemsSource="{x:Bind ComboStrings}">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding}"/>
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
</StackPanel>

和背后的代码

public sealed partial class MainPage : Page
{
    private string[] comboStrings = { "One", "Two", "Three" };
    public List<String> ComboStrings
    {
       get { return new List<string>(comboStrings); }
    }

    public MainPage()
    {
        this.InitializeComponent();
        DataContext = this;
        BrowserCombo.SelectedIndex = 1;
    }

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        // BrowserCombo.SelectedIndex = 1;
    }
}

我希望它非常简单,所以没有MVVM - 我仍然需要学习这个概念。

说明:

  1. 我可以将 SelectedIndex 放在XAML文件中。同样的问题。
  2. 如果我将 SelectedIndex 放在 Page_Loaded 事件处理程序中,它可以正常工作。
  3. 在经典桌面XAML(又名WPF)中没有问题。
  4. 似乎项目列表将在XAML-WinRt和XAML-WPF之间以不同方式填充。访问 SelectedIndex 属性的最早点是什么?

1 个答案:

答案 0 :(得分:2)

当您尝试在页面构造函数中设置BrowserCombo.SelectedIndex = 1;时,您的 ItemsSource 仍然是 null ,因此会出现此异常。您正在使用x:Bind - 如果您调试生成的 MainPage.g.cs 文件并在那里放置一些断点:

public void Loading(global::Windows.UI.Xaml.FrameworkElement src, object data)
{
    this.Initialize();
}

public void Initialize()
{
    if (!this.initialized)
    {
        this.Update();
    }
}

public void Update()
{
    this.Update_(this.dataRoot, NOT_PHASED);
    this.initialized = true;
}

您将看到正在加载事件中正在解析x:Bind - 这解释了为什么在构造函数中您仍然在 ItemsSource null >

另一件事就是使用旧的 Binding - 当你设置DataContext = this;时它会被解析,但是你使用的是x:Bind,实际上你并不需要设置 DataContext - 它在这里没有任何改变。如果您将ItemsSource="{x:Bind ComboStrings}"替换为ItemsSource="{Binding ComboStrings}",那么您的代码应该可以使用,否则您可以删除该行DataContext = this;

另一个有趣的事情是XAML中定义的绑定的顺序也会导致类似的麻烦 - 例如,如果您像这样定义 ComboBox

<ComboBox Name="BrowserCombo" SelectedIndex="{x:Bind Index}" ItemsSource="{x:Bind ComboStrings}">

然后你也会得到例外 - 在设置集合之前, SelectedIndex 正在解决。与工作正常的情况相反:

<ComboBox Name="BrowserCombo" ItemsSource="{x:Bind ComboStrings}" SelectedIndex="{x:Bind Index}">