C# - 相対ソースルートの親コントロールのプロパティを子クラスの添付プロパティにバインドすると、アプリがクラッシュします

okwaves2024-01-25  10

Entry コントロールの添付プロパティを、ContentView であるルート親のプロパティにバインドしようとしています。 (主に、NumBehaviors クラスで呼び出されたビューの ViewModel(BindingContext) を使用/アクセスするため) デバッグで問題が明確に特定されないまま、アプリケーションが起動する前にクラッシュします:

オブジェクトの現在の状態のため、操作は無効です。

D:\a\1\s\Xamarin.Forms.Core\ Binding.cs:153 の Xamarin.Forms.Binding.ApplyRelativeSourceBinding (Xamarin.Forms.BindableObject targetObject, Xamarin.Forms.BindableProperty targetProperty) [0x00041] で

[エラー] 致命的な未処理例外: System.InvalidOperationException: オブジェクトの現在の状態のため、操作は無効です。

1- 何か間違ったことをしているのでしょうか (おそらくバインディングコンテキスト)?それとも、Xamarin はまだ wpf ほど適切にバインディングを処理していないのでしょうか (ElementName がないなど)?

2- デバッグ エラー/例外がそれほど明確ではないのはなぜですか?

MainView.xaml:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:Helpers="clr-namespace:App.Helpers"
             xmlns:Behaviors="clr-namespace:App.Behaviors"
             HorizontalOptions="FillAndExpand"
             VerticalOptions="Center"
             x:Class="App.Views.MainView">

<Entry>
     <Entry.Behaviors>
          <Behaviors:NumBehaviors Helpers:HelperClass.Vm=
           "{Binding Source={RelativeSource AncestorType={x:Type ContentView}}, Path=VM}"/>
     </Entry.Behaviors>
</Entry>

HelperClass.cs

public static BindableProperty VmProperty = 
       BindableProperty.Create("Vm", typeof(object), typeof(HelperClass), null);

public static object GetVm(BindableObject bindable)
{
    return (object)bindable.GetValue(VmProperty);
}

public static void SetVm(BindableObject bindable, object value)
{
    bindable.SetValue(VmProperty, value);
}

MainView.cs

public object VM {get; set;}

public MainView()
{
InitializeComponent();
VM  = (object) new MyViewModel();
BindingContext = VM;
}

NumBehaviors.cs

...
void OnEntryTextChanged(object sender, TextChangedEventArgs args) {
     var usedvm = HelperClass.GetVm((BindableObject)sender);
}

次のコードを使用することもできますが、これは悪い考えだと思います。Entry の BindingContext がそのルート親の BindingContext と異なる場合、また柔軟性がない場合には役に立ちません。

...
void OnEntryTextChanged(object sender, TextChangedEventArgs args) {
     var usedvm = ((Entry)sender).BindingContext;
}

追記: 私のアプローチが良くないのかもしれませんが、それを達成するためのより良いアプローチを受け入れるつもりです。

編集

Xamarin.Forms 4.8.0.1364 の使用

AncestorType={x:Type ContentView}} の代わりに AncestorType={x:Type local:MainView}} を使用しても同じ結果が得られました。

おそらくそれはこのオペに関連していますXamarin.Forms の未解決の問題 [バグ] AncestorType #9839 を使用するとコンパイルされたバインディングが機能しない

提供された Github のリンクから詳細を確認できます。

– ウェンディ ザン - MSFT

2020 年 9 月 7 日 9:49

1

関連: forums.xamarin.com/Discussion/183883/…

– クレイ・ブルックス

2020 年 9 月 11 日 17:41

@ClayBrooks 動作しています。受け入れられるように回答として入力していただけますか。また、間違いを犯したと思います。 Helpers:HelperClass.Vm.. は、Entry ではなく <Entry.. の添付プロパティである必要があります。 .Behaviors:NumBehaviors それ以外の場合は HelperClass.GetVm((BindableObject)sender);何らかの方法で送信者 (=Entry) の代わりにパラメータとして Sender.Behaviors:NumBehaviors を指定しない限り、常に null を返します。

– Cfun

2020 年 9 月 11 日 19:19



------------------------

RelativeSource はその祖先のバインディング コンテキストを見つけることができますが、動作は現在のビジュアル ツリーにありません。

バインディング コンテキストを示すためにこれを使用することをお勧めします。

Command="{Binding BindingContext.YourCommand, Source={x:Reference PageName}}"

YourCommand は BindingContext からアクセスできる必要があり、PageName は、<ContentPage ... x:Name="PageName" のように、それを囲む ContentPage の属性に設定する必要があります。

詳細については、こちらをご覧ください。最初の解決策を提供したそのリンクの男性に感謝します。

1

ユーザーが混乱しないように、質問の例のコンテキストに対する有効な回答にソリューションを適応させていただけますか?そして最も重要なのは、この場合 GetVm() のパラメータ オブジェクトが何になるかです。

– Cfun

2020 年 9 月 12 日 9:32



------------------------

この問題を回避するもう 1 つの解決策は、Attached プロパティを <Entry.Behaviors:NumBehaviors> から移動してデザインを変更することです。 <エントリ> へ:

<Entry Helpers:HelperClass.Vm="{Binding Source={RelativeSource AncestorType={x:Type ContentView}},
                               Path=VM}">
     <Entry.Behaviors>
          <Behaviors:NumBehaviors/>
     </Entry.Behaviors>
</Entry>

この変更により、質問コードでプロパティ Vm をオブジェクト <Entry.Be に付加していた間違いも修正されます。動作:NumBehaviors>オブジェクト Sender(=Entry) (var usedvm = HelperClass.GetVm((BindableObject)sender);) から取得しようとしましたが、常に null を返します。

1

あなたがご自身で問題を解決し、その解決策を私たちに共有してくださったことを嬉しく思います。回答として受け入れていただければ、同様の問題を抱えている他のコミュニティにとって有益です。

– 呉張龍 - MSFT

2020 年 9 月 14 日 3:18

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。