更改ListBox SelectedValuePath会引发异常

时间:2013-10-22 06:22:35

标签: c# .net wpf listbox selecteditem

我写了一篇关于CodeProject的文章的快速申请(全文here。)您可以直接从here下载此问题的源代码。

这是一个非常简单的窗口,它有一个带有简单对象的ListBox(3个属性:2个字符串,1个int)。

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

我在后面的代码中设置了SelectedValuePath,因此用户可以从组合框中选择一个属性,并查看标签中的当前SelectedValue

ComboBox设置为类型为

的对象
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行。运行演示:

  • 在SelectedValuePath组合框中选择前两个字符串属性中的任何一个(第二个)。
  • 更改列表框上的选项(您应该看到SelectedValue相应更改)
  • 将第二个组合框中的选择更改为int属性(实际上是字符串表示)。 引发错误的异常:“输入字符串的格式不正确”

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

在设置之前将SelectedValuePath设置为null似乎可以解决问题。有什么建议为什么抛出你的例外以及问题是什么?

修改: 这是一个包含更多属性类型的新演示。它还会显示引发的错误,并跟踪SelectedIndexDownload new demo

1 个答案:

答案 0 :(得分:0)

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

编辑:好的,问题是SelectedValuePath只是希望在你告诉字符串时将字符串转换为字符串。但是当你告诉它它的'value'应该是一个整数时,它希望你传入某种整数的字符串版本。然后,它可以将其转换为适当的整数值。你仍然传递一个名字,它不能将它转换为整数并告诉你。如果您单步执行代码并将名称更改为“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;
    }