【问题标题】:EventToCommandBehavior throws InvalidOperationException in MAUI for checkboxEventToCommandBehavior 在 MAUI 中为复选框抛出 InvalidOperationException
【发布时间】:2022-11-17 19:26:12
【问题描述】:

选中/取消选中复选框后,我需要运行命令。复选框通过 StackLayout 的项目源呈现在页面中,EventToCommandBehavior 来自 MAUI CommunityToolkit。

当应该呈现页面时抛出异常,很可能是在分析和处理 XAML 时。异常消息说:“由于对象的当前状态,操作无效。”,这不是很有帮助(我缺少什么状态,谁是所有者,什么是无效的)。

也许 callstact 会帮助某人?

  at Microsoft.Maui.Controls.Binding.ApplyRelativeSourceBinding(BindableObject targetObject, BindableProperty targetProperty) in D:\a\_work\1\s\src\Controls\src\Core\Binding.cs:line 152
  at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
  at Android.App.SyncContext.<>c__DisplayClass2_0.<Post>b__0() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:line 36
  at Java.Lang.Thread.RunnableImplementor.Run() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:line 36
  at Java.Lang.IRunnableInvoker.n_Run(IntPtr jnienv, IntPtr native__this) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net6.0/android-31/mcw/Java.Lang.IRunnable.cs:line 84
  at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V callback, IntPtr jnienv, IntPtr klazz) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrap

我在 Xamarin 中多次使用相同的技术。它按预期在那里工作,但在 MAUI 中,以下代码抛出 InvalidOperationException。内容页面和视图模型已正确创建(构造函数通过),但稍后某处抛出异常,老实说不知道为什么。

<StackLayout 
    BindableLayout.ItemsSource="{Binding GameVariants}">
    <BindableLayout.ItemTemplate>
        <DataTemplate x:DataType="bindable:SelectExpansion">
            <StackLayout Orientation="Horizontal" VerticalOptions="Center">
                <CheckBox
                    IsEnabled="{Binding IsExpansion}"
                    IsChecked="{Binding Selected}">
                    <CheckBox.Behaviors>
                        <toolkit:EventToCommandBehavior
                            EventName="CheckedChanged"
                            Command="{Binding Source={RelativeSource AncestorType={x:Type vm:SelectExpansionsPageViewModel}}, Path=SelectExpansionCommand}"
                            CommandParameter="{Binding .}" />
                    </CheckBox.Behaviors>
                </CheckBox>
                <Label Text="{Binding Expansion}" VerticalTextAlignment="Center" />
            </StackLayout>
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

后面的代码仅包含通过依赖项设置上下文。

public partial class SelectExpansionsPage : ContentPage
{
    public SelectExpansionsPage(SelectExpansionsPageViewModel vm)
    {
        BindingContext = vm;
        InitializeComponent();
    }
}

这是页面的视图模型。

public partial class SelectExpansionsPageViewModel : ObservableObject
{
    public SelectExpansionsPageViewModel(Game state)
    {
        GameVariants = new ObservableCollection<SelectExpansion>(AvailableExpansions.Expansions.Select(item =>
        {
            item.Selected = state.Expansions.Contains(item.Expansion);

            return item;
        }));
    }

    public ObservableCollection<SelectExpansion> GameVariants { get; }
    
    [RelayCommand]
    public void SelectExpansion(SelectExpansion item)
    {
        Debug.WriteLine("Select item changed");
    }
}

【问题讨论】:

  • 切换构造函数中语句的顺序。最后设置 BindingContext;您希望在 Maui 尝试执行绑定之前一切就绪。
  • 谢谢,@ToolmakerSteve,事实上,我一开始就已经使用过它,但是顺序没有区别。
  • 当不是 toolkit:EventToCommandBehavior 的一部分时测试绑定源。将成员public string TestString { get; set; } = "TEST"添加到SelectExpansionsPageViewModel,并将ItemTemplate标签更改为&lt;Label Text="{Binding Source={RelativeSource AncestorType={x:Type vm:SelectExpansionsPageViewModel}}, Path=TestString}"。如果可行,那么我认为当在 ItemTemplate 中使用时,您在 EventToCommandBehavior 中发现了一个错误。在 maui-community-toolkit github 添加问题。

标签: .net xamarin xamarin.forms .net-maui maui-community-toolkit


【解决方案1】:

经过一些研究,我发现行为不是可视化树的一部分(抱歉,链接丢失了)。

要克服这一点,必须通过引用来引用源绑定,请参阅“这个”这是指内容页面的x:NameViewModel 只是ContentPage 的强类型属性,它引用未装箱的BindingContext

<?xml version="1.0" encoding="utf-8"?>

<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:vm="clr-namespace:Everdell.ViewModels;assembly=Everdell"
    xmlns:toolkit="http://xamarin.com/schemas/2020/toolkit"
    x:Class="Everdell.Views.SelectExpansionsView"
    x:DataType="vm:SelectExpansionsViewModel"
    x:Name="This">
    <ContentPage.Content>
        <CheckBox>
            <CheckBox.Behaviors>
                <toolkit:EventToCommandBehavior
                    EventName="CheckedChanged"
                    Command="{Binding Source={x:Reference This}, Path=ViewModel.SelectExpansionCommand}"
                    CommandParameter="{Binding .}" />
            </CheckBox.Behaviors>
        </CheckBox>
    </ContentPage.Content>
</ContentPage>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多