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

Why I get exception when setting ComboBox.SelectedIndex?

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

我遇到异常:

Value does not fall within the expected range.

SelectedIndex 属性.

这是我的 XAML UWP 应用程序。

<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)中不会有问题。

XAML-WinRt 和 XAML-WPF 之间的项目列表似乎会有所不同。最早访问SelectedIndex属性的点是什么?

出现此异常是因为当您尝试在页面的构造函数中设置 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 正在 Loading 事件中得到解决 - 这解释了为什么在构造函数中您仍然有 nullItemsSource.

另一件事是旧的 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}">