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

Xamarin中CheckBox触发命令时无效转换异常的排查与解决

Xamarin中InputKit CheckBox绑定命令触发无效转换异常的解决

我在Xamarin项目中,尝试通过InputKit的CheckBox勾选时,将列表项从待办集合移除并添加到已完成集合。ImageButton绑定的RemoveTodoCommand可以正常工作,但CheckBox绑定的CompleteTodoCommand触发时,抛出「Specified cast is not valid.」(无效转换)异常。


相关代码

XAML代码

<ListView ItemsSource="{Binding TodoListItems}" x:Name="todoList">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <FlexLayout JustifyContent="SpaceBetween" Padding="20,0">
                    <ContentView>
                        <FlexLayout AlignItems="Center" >
                            <input:CheckBox IsChecked="{Binding Complete}" 
                                            CheckChangedCommand="{Binding Path=BindingContext.CompleteTodoCommand, Source={x:Reference todoList}}"
                                            CommandParameter="{Binding .}"
                                            />
                            <Label Text="{Binding TodoText}" Padding="10,0,0,0" FontSize="Large"/>
                        </FlexLayout>
                    </ContentView>
                    
                    <ImageButton Source="trash_icon.png" 
                                 Command="{Binding Path=BindingContext.RemoveTodoCommand, Source={x:Reference todoList}}"
                                 CommandParameter="{Binding .}"
                                 Scale="1.2" BackgroundColor="White"
                                 />
                    
                </FlexLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
    
</ListView>

ViewModel代码

{
    private ObservableCollection<TodoItem> todoListItems;

    
    public ObservableCollection<TodoItem> TodoListItems
    {
        get { return todoListItems; }
        set { todoListItems = value; }
    }

    private ObservableCollection<TodoItem> completedTodoItems;

    public ObservableCollection<TodoItem> CompletedTodoItems
    {
        get { return completedTodoItems; }
        set { completedTodoItems = value; }
    }



    public TodoListViewModel()
    {
        todoListItems = new ObservableCollection<TodoItem>();
        TodoListItems.Add(new TodoItem("Walk the duggo",false));
        TodoListItems.Add(new TodoItem("Do the washing",false));
        TodoListItems.Add(new TodoItem("Brush off Cheeto dust",false));

        CompletedTodoItems = new ObservableCollection<TodoItem>();
    }
    public ICommand AddTodoCommand => new Command(AddTodoItem);
    public string NewTodoInputValue { get; set; }
    void AddTodoItem() 
    {
        TodoListItems.Add(new TodoItem(NewTodoInputValue));
    }

    public ICommand RemoveTodoCommand => new Command(RemoveTodoItem);
    
    void RemoveTodoItem(object o)
    {
        TodoItem todoItemBeingRemoved = o as TodoItem;
        TodoListItems.Remove(todoItemBeingRemoved);
    }

    public ICommand CompleteTodoCommand => new Command(CompleteTodo);

    void CompleteTodo(object o) 
    {
        
        TodoItem todoItemCompleted = o as TodoItem;
        todoListItems.Remove(todoItemCompleted);

        CompletedTodoItems.Add(todoItemCompleted);
    }

}

MainPage.xaml.cs代码

public partial class MainPage : ContentPage
{
    TodoListViewModel ViewModel { get; set; }
    public MainPage()
    {
        InitializeComponent();
        this.ViewModel = new TodoListViewModel();
    }
}

异常排查

已确认ObservableCollection已完成初始化,AddTodo和RemoveTodo命令均可正常工作。异常栈追踪如下:

0x1C in TodoAppXamarin.ViewModels.TodoListViewModel.CompleteTodo at C:\Users\johns\source\repos\TodoAppXamarin\TodoAppXamarin\TodoAppXamarin\ViewModels\TodoListViewModel.cs:64,4
at C:\Users\johns\source\repos\TodoAppXamarin\TodoAppXamarin\TodoAppXamarin\ViewModels\TodoListViewModel.cs(64)

进一步排查发现,无论在何处向CompletedTodoItems集合添加TodoItem都会触发异常——即使在ViewModel构造函数中添加测试项,也会在Android项目MainActivity的OnCreate方法中抛出异常:

public TodoListViewModel()
{
    todoListItems = new ObservableCollection<TodoItem>();
    TodoListItems.Add(new TodoItem("Walk the duggo", false));
    TodoListItems.Add(new TodoItem("Do the washing", false));
    TodoListItems.Add(new TodoItem("Brush off Cheeto dust", false));

    CompletedTodoItems = new ObservableCollection<TodoItem>();
    CompletedTodoItems.Add(new TodoItem("Do the dishes",true));
}

对应异常栈:

>   0x1F in TodoAppXamarin.Droid.MainActivity.OnCreate at C:\Users\johns\source\repos\TodoAppXamarin\TodoAppXamarin\TodoAppXamarin.Android\MainActivity.cs:17,13    C#

解决方法

修改CompleteTodo方法的参数转换方式,将as安全转换改为直接强制转换后,问题得以解决:

void CompleteTodoItem(object o)
{
    TodoItem completedTodoItem=(TodoItem)o;
    
    Console.WriteLine(completedTodoItem.TodoText);
    TodoListItems.Remove(completedTodoItem);
    
    CompletedTodoItems.Add(completedTodoItem as TodoItem);
    Console.WriteLine(CompletedTodoItems.Contains(completedTodoItem));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:20:13