更改列表框选定值路径将引发异常

本文关键字:路径 异常 列表 | 更新日期: 2023-09-27 18:36:18

我为一篇关于CodeProject的文章写了一个快速应用程序(完整的文章在这里。您可以直接从此处下载此问题的源代码)。

这是一个非常简单的窗口,其中包含一个包含简单对象的列表框(3 个属性:2 个字符串,1 个整数)。

public class MyShape
{
    public string ShapeType  { get; set; }
    public string ShapeColor { get; set; }
    public int    ShapeSides { get; set; }
}

我在代码隐藏中设置SelectedValuePath,以便用户可以从组合框中选择一个属性,并在标签中查看当前SelectedValue

组合框设置为以下类型的对象:

public class PropertyObject
{
    public string PropertyName { get; set; }
    public string PropertyType { get; set; }
}

这两个属性都是字符串,因此,作为SelectedValuePath的输入应该有效。

我像这样设置值:

private void ShapeClassPropertiesCmbx_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ComboBox cmbx = (ComboBox)sender;
        PropertyObject prop_ob = ((PropertyObject)cmbx.SelectedItem);
        string name = prop_ob.PropertyName;
        var item_index = SourceListBox.SelectedIndex;
        //SourceListBox.SelectedValuePath = null;       // without this, we get a null exceptions when going from string to int properties for some reason.
        SourceListBox.SelectedValuePath = name;
        SourceListBox.SelectedIndex = item_index;
    }

(如果您下载代码,它是 MainWindow.xaml.cs 上的第 79 行)。

当我将所选值从string更改为int时,会发生异常。为避免混淆,两者都string要显示的属性的表示形式。

要重现错误,请注释掉第 79 行。运行演示:

  • 选择"选定值路径"组合框(第二个)上的前 2 个字符串属性中的任何一个。
  • 更改列表框上的选择(您应该看到SelectedValue相应地更改)
  • 将第二个组合框中的选择更改为 int 属性(这实际上是一个字符串表示形式)。引发异常并显示错误:"输入字符串格式不正确"

奇怪的是:如果您重复这些步骤,但首先选择 int 属性,它就可以正常工作。然后更改为字符串,仍然可以正常工作。回到 int,抛出异常。

在设置之前将SelectedValuePath设置为 null 似乎可以解决问题。任何建议为什么抛出您的异常以及问题是什么?

编辑:下面是包含更多属性类型的新演示。它还将显示抛出的错误,并跟踪SelectedIndex:下载新演示。

更改列表框选定值路径将引发异常

如果

注释掉第 78 行,看起来item_index是未定义的。编辑:哎呀!应该是第 79 行。

编辑:好的,问题是SelectedValuePath只是期望将字符串转换为字符串,当你告诉它期望一个字符串时。但是当你告诉它它的"值"应该是一个整数时,它希望你传入某种整数的字符串版本。然后,它可以将其转换为适当的整数值。您仍在传递一个名称,它无法将其转换为整数并告诉您。如果单步执行代码并将名称更改为"2"而不是"ShapeSides",它将正确运行。我建议检查所选值的索引,如果类型应该是字符串,则设置 name = SelectedValue.ToString(),如果它应该是整数,则设置 name = SelectedIndex.ToString()。

    switch (SourceListBox.SelectedIndex)
    {
        case 0:
        case 1:
            name = SourceListBox.SelectedValue.ToString();
            break;
        case 2:
            name = SourceListBox.SelectedIndex.ToString();
            break;
    }