You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms绑定对象添加全局值时出现无效转换异常

问题场景与异常

尝试构建包含重复自定义Entry的布局:外层通过BindableLayout循环渲染多个Entry组件,输入文本时显示SuggestedText候选列表(ViewModel构造时初始化的ObservableCollection<string>)。静态绑定数据源时功能正常,但动态绑定SuggestedText时,页面导航前抛出异常:

System.InvalidCastException: Specified cast is not valid.
  at Xamarin.Forms.BindableLayout+<>c.<.cctor>b__19_4 (Xamarin.Forms.BindableObject b) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\BindableLayout.cs:24 
  at Xamarin.Forms.BindableObject.CreateAndAddCo...

即使将SuggestedText移至MyObjectLists中,异常仍会触发。


错误根源

  1. ListView误用BindableLayout模板:BindableLayout.ItemTemplate仅适用于布局控件(如StackLayout、Grid),ListView自身拥有独立的ItemTemplate属性,混用两者会导致Xamarin.Forms内部类型转换失败,直接引发InvalidCastException。
  2. ViewModel中集合未初始化:SuggestedText在调用FillSuggestText()添加元素前未实例化,存在空引用风险。
  3. 数据上下文不匹配:外层BindableLayout的数据源是ObservableCollection<string>,模板内Entry绑定LicensePlate属性时,当前上下文是string类型,不存在该属性,会导致绑定失败。

解决方案

1. 修正ListView的模板定义

将ListView内部的BindableLayout.ItemTemplate替换为原生ListView.ItemTemplate,且必须用ViewCell包裹内容:

<ListView ItemsSource="{Binding Path=BindingContext.SuggestedText, Source={x:Reference thispage}}" 
          x:Name="LicensePlateListView" IsVisible="{Binding IsVisible}" CachingStrategy="RecycleElement" 
          BackgroundColor="White" ItemTapped="OnItemTapped" AbsoluteLayout.LayoutBounds="20,110,269,160" 
          AbsoluteLayout.LayoutFlags="None">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout BackgroundColor="White">
                    <Label Text="{Binding .}" FontSize="16" TextColor="#FF464859"/>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

2. 初始化ViewModel中的ObservableCollection

在ViewModel构造函数中提前实例化SuggestedText,避免空引用:

public MyViewModel (MyObject parameters, INavigation navigation)
{
    MyObjectLists = parameters;
    // 提前初始化集合
    SuggestedText = new ObservableCollection<string>();
    
    Device.BeginInvokeOnMainThread(() => {
        try
        {
            FillSuggestText();
        }
        catch (Exception ex)
        {
            IsBusy = false;
            Helper.GlobalErrorTrashing(ex);
        }
    });
}

3. 修正数据上下文绑定

外层BindableLayout的数据源ListofLicensePlates若为ObservableCollection<string>,则Entry的Text绑定应改为{Binding .};若需要LicensePlate和Index属性,需将集合元素改为自定义类:

// 定义LicensePlateItem类
public class LicensePlateItem
{
    public string LicensePlate { get; set; }
    public int Index { get; set; }
    public bool IsVisible { get; set; }
}

// 更新MyObject中的集合类型
public class MyObject
{
   public List<TextObject> TextList { get; set; }
   public ObservableCollection<LicensePlateItem> ListofLicensePlates { get; set; }
}

验证

  1. 编译运行修正后的代码
  2. 导航至目标页面,确认无初始化异常
  3. 输入文本触发ShowListView,检查候选列表是否正常显示

内容的提问来源于stack exchange,提问作者Amature123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 20:35:28