将Xamarin ListView绑定到IEnumerable <Person>时,InvalidCastException

时间:2019-07-10 18:25:39

标签: c# xaml xamarin

我在Xamarin应用程序中具有此ListView:

<ListView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{x:Static local:Person.All}" x:Name="list">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Label Text="{Binding Name}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

我正在尝试通过将IEnumerable<Person>属性设置为新的可枚举来将其绑定到ItemsSource。 (是的,我知道我应该创建一个视图模型,但是我满怀激情地讨厌MVVM!)但是当枚举中有数据时,我会收到此错误:

  

System.InvalidCastException:指定的转换无效。

设置ItemsSource后不会立即发生这种情况;我有一个包含设置操作的try / catch块,但没有异常被捕获。相反,一旦我退出设置ItemsSource的方法,它就会发生。没有与此错误相关联的堆栈跟踪。这就是我从一些通用的“未处理的异常”消息中脱颖而出的原因。

这是我设置ItemsSource的方法:

private void BtnLogIn_Clicked(object sender, EventArgs e)
{
    try
    {
        // log in
        var req = WebRequest.CreateHttp($"http://{Configuration.Hostname}/api/login?systemID=1091&login={txtLogin.Text}&password={txtPassword.Text}");
        var resp = (HttpWebResponse)req.GetResponse();
        var cookiesData = resp.Headers.Get("Set-Cookie");
        var regex = new Regex($@"{CookieManager.LoginCookieID}=(.*); expires=.*");
        Login.CookieValue = regex.Match(cookiesData).Groups[1].Captures[0].Value;
        list.ItemsSource = Person.All; // reload person list
    }
    catch (Exception ex)
    {
        DisplayAlert("Error", ex.ToString(), "OK");
    }
}

(是的,我知道在URL中输入密码是一个坏主意;这只是概念的证明!)

这是Person类:

public class Person
{
    public static IEnumerable<Person> All => GetWebData<IEnumerable<Person>>($"http://{Configuration.Hostname}/api/people", CookieManager.LoginCookieID, Login.CookieValue);

    private static T GetWebData<T>(string url, string cookieKey, string cookieValue)
    {
        try
        {
            var web = WebRequest.CreateHttp(url);
            web.Headers["Set-Cookie"] = $"{cookieKey}={cookieValue}";
            var stream = web.GetResponse().GetResponseStream();
            var sr = new StreamReader(stream);
            T data;
            var json = sr.ReadToEnd();
            sr.Close();
            try
            {
                data = JsonConvert.DeserializeObject<T>(json);
            }
            catch
            {
                data = JsonConvert.DeserializeObject<IEnumerable<T>>(json).Single();
            }
            return data;
        }
        catch
        {
            // could not access data, maybe not logged in yet?
            return default(T);
        }
    }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string Name => $"{FirstName} {LastName}";
}

1 个答案:

答案 0 :(得分:0)

我知道了-看来<Label Text="{Binding Name}" />作为DataTemplate无效;我将Label更改为TextCell,一切正常!