ComboBox SelectionChanged事件处理程序中的InvalidCastException

时间:2018-12-17 22:42:02

标签: wpf autocad

此代码运行良好:

 private void Combobox1_Loaded(object sender, RoutedEventArgs e)
 {
     var combo = (ComboBox)sender;
     var pointGroupList = (List<PointGroup>)combo.ItemsSource;
     combo.ItemsSource = pointGroupList.Select(group => group.Name);
 }

但是这个根本不起作用:

private void Combobox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var combo = (ComboBox)sender;
    var pointGroupList = (List<PointGroup>)combo.ItemsSource;
    textBlock1.Text = "num of points:" + pointGroupList.Find(group => group.Name == (string)combo.SelectedItem).PointsCount.ToString();
}

这是我的输出窗口中的消息:

  

System.InvalidCastException:无法转换类型为“ WhereSelectListIterator2 [Autodesk.Civil.DatabaseServices.PointGroup,System.String]”的对象来键入“ System.Collections.Generic.List1 [Autodesk.Civil.DatabaseServices.PointGroup]”。在_01_COGO_Points.ModalDialog_1.Combobox1_SelectionChanged(Object sender,SelectionChangedEventArgs e)中的D:\ 00材料\ c3d \ c#\ examples \ ACAD \ 01 COGO Points \ Window.xaml.cs:第49行

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

您在Loaded事件中所做的事情很奇怪。我不建议您这样做,因为它会破坏您的绑定。如果这样做的原因是Name属性显示在ComboBox中,则应该使用DataTemplate。像这样:

<Window.Resources>
    <DataTemplate x:Key="pntGroupTemplate" DataType="{x:Type ac:PointGroup}">
        <TextBlock Text="{Binding Name}"/>
    </DataTemplate>
</Window.Resources>

,您当然需要在Window中添加一个命名空间。像这样:

xmlns:ac="clr-namespace:Autodesk.Civil.DatabaseServices;assembly=AeccDbMgd"

我没有Civil,因此不确定这是否正确,但是应该接近。如果这一方法不太正确,Intellisense应该能够为您提供正确的路径。

并在组合框中

<ComboBox ItemTemplate="{StaticResource pntGroupTemplate}" ...  />

我最好的建议是完全摆脱Combobox1_Loaded事件处理程序中的所有代码,并在xaml中创建一个DataTemplate以使用上面的代码片段显示Name属性。最后,从此更改您的lambda表达式:

group => group.Name == (string)combo.SelectedItem

对此:

group => group.Name == (combo.SelectedItem as PointGroup)?.Name

您遇到的异常是由于第二行。当您在Loaded事件中调用Select方法时,它将返回IEnumerable<string>,因此,当您将ItemsSource强制转换为List<PointGroup>时,一切都在许多不同的地方方式:-)。

您正在做的另一个问题是,SelectedItemstring,并且没有Name属性。

希望有帮助