简体   繁体   English

ObservableCollection 导致无效的强制转换异常

[英]ObservableCollection causing invalid cast exception

I'm completely new to XAML and have been trying to build a small phone app based on Microsoft's sample here: ListView binding .我对 XAML 完全陌生,并且一直在尝试基于此处的 Microsoft 示例构建一个小型手机应用程序: ListView binding When my code runs I get a "Specified cast is not valid" exception at the point marked below.当我的代码运行时,我在下面标记的点处收到“指定的强制转换无效”异常。 I'm not sure how much of this is relevant but bear with me.我不确定其中有多少是相关的,但请耐心等待。

This is the XAML code for part of the page:这是部分页面的 XAML 代码:

<ListView x:Name="ListCoords" ItemsSource="{Binding Coordinates}">
<ListView.ItemTemplate>
    <DataTemplate>
        <StackLayout Margin="0" Orientation="Horizontal">
            <Label x:Name="LabelA" HeightRequest="32" WidthRequest="100" Text="{Binding Path=angle, StringFormat='{0:F2}'}" />
            <Label x:Name="LabelX" HeightRequest="32" WidthRequest="100" Text="{Binding Path=x, StringFormat='{0:F2}'}" />
            <Label x:Name="LabelY" HeightRequest="32" WidthRequest="100" Text="{Binding Path=y, StringFormat='{0:F2}'}" />
        </StackLayout>
    </DataTemplate>
</ListView.ItemTemplate>

The relevant parts of the cs code behind the page is like this:页面后面的cs代码相关部分是这样的:

public partial class PCDPage : ContentPage
{

    public ObservableCollection<Coordinate> CoordinateList = new ObservableCollection<Coordinate> ();
    public ObservableCollection<Coordinate> Coordinates { get { return CoordinateList; } }

    public PCDPage()
    {
        InitializeComponent();
        ListCoords.ItemsSource = CoordinateList;
    }

    ... Code here responds to a button press and calls the following ...
    
    //
    // Calculate and display a table of hole coordinates
    //
    private void CalculateCoordinates()
    {
        // Start a new list
        CoordinateList.Clear();

        double x, y, a, b;

        for (int i = 0; i < count; i++)
        {
            ... Calculate a, x, y
            
            // Add the corrdinate to the list
            CoordinateList.Add(new Coordinate(a, x, y));      <<<< - Exception
        }

        ... Finish off
    }

And the little coordinate class is:而小坐标 class 是:

    public class Coordinate
{
    public Coordinate()
    {

    }

    public Coordinate(double va, double vx, double vy)
    {
        angle = va;
        x = vx;
        y = vy;
    }

    public double angle { get; set; }
    public double x { get; set; }
    public double y { get; set; }
}

When I run my app it crashes at the point marked on adding the first coordinate to the list.当我运行我的应用程序时,它会在将第一个坐标添加到列表时标记的点崩溃。 While it's stopped in the debugger, I can hover over the CoordinateList and see that it contains one item as expected.虽然它在调试器中停止,但我可以在 CoordinateList 上使用 hover 并查看它是否包含预期的一项。 In the XAML, I can do the same thing with the binding.在 XAML 中,我可以对绑定做同样的事情。 So it looks to me as if the problem occurs after adding the item and before returning to my code.所以在我看来,好像问题是在添加项目之后和返回我的代码之前发生的。 Have I missed something obvious or is there a subtlety that I haven't learnt about yet?我是否遗漏了一些明显的东西,还是有一些我尚未了解的微妙之处?

Thanks in advance提前致谢

The properties of the Coordinate class are of type double, but the "Text" property of the Labels is string.坐标 class 的属性是双精度类型,但标签的“文本”属性是字符串。 You need to create a converter您需要创建一个转换器

public  class DoubleToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        return value!=null?((double)value).ToString():"";
    }
 
    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        return null;
    }
}

<ListView x:Name="ListCoords" ItemsSource="{Binding Coordinates}">
    <ListView.Resources>
        <l:DoubleToStringConverter x:Key="converter" />
    </ListView.Resources>
<ListView.ItemTemplate>
    <DataTemplate>
        <StackLayout Margin="0" Orientation="Horizontal">
            <Label x:Name="LabelA" HeightRequest="32" WidthRequest="100" Text="{Binding Path=angle, StringFormat='{0:F2}',Converter={StaticResource converter}}" />
            <Label x:Name="LabelX" HeightRequest="32" WidthRequest="100" Text="{Binding Path=x, StringFormat='{0:F2}',Converter={StaticResource converter}}" />
            <Label x:Name="LabelY" HeightRequest="32" WidthRequest="100" Text="{Binding Path=y, StringFormat='{0:F2}',Converter={StaticResource converter}}" />
        </StackLayout>
    </DataTemplate>
</ListView.ItemTemplate>

"l" would be the prefix to indicate the namespace of the DoubleToStringConverter class. “l”将是指示 DoubleToStringConverter class 的命名空间的前缀。

xmlns:l="clr-namespace:MyNamespace"

namespace MyNamespace
{
    public class DoubleToStringConverter : IValueConverter
    {

But in this case the converter is not necessary, that is not the error.但在这种情况下,转换器不是必需的,这不是错误。

I have found that it is necessary to include the content inside the View of the ViewCell我发现有必要在 ViewCell 的 View 中包含内容

<ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ViewCell.View>
                        <StackLayout Margin="0" Orientation="Horizontal">
                            <Label  x:Name="LabelA" HeightRequest="32" WidthRequest="100" Text="{Binding Path=angle, StringFormat='{0:F2}'}" />
                            <Label  x:Name="LabelX" HeightRequest="32" WidthRequest="100" Text="{Binding Path=x, StringFormat='{0:F2}'}" />
                            <Label  x:Name="LabelY" HeightRequest="32" WidthRequest="100" Text="{Binding Path=y, StringFormat='{0:F2}'}" />
                        </StackLayout>
                    </ViewCell.View>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>

Sorry for my bad English.对不起,我的英语不好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM