7

一連のコードに関連する問題がありますが、それを切り分けました。TL;DR; が必要な場合。さらに下にジャンプします。少しコンテキストが必要な場合は、これが私の状況です。

バインディング用に 3 つのデータ コンバーターを作成しました。それらの 1 つは「文字列プレフィックス」です。これは、入力したものに固定文字列をプレフィックスとして付けます。現在の例では、その固定文字列は"ms-appx:///cache/". 2 つ目はstring型を にImageSource変換し、3 つ目は複数のコンバーターをチェーンします。

次に、という名前の Xaml リソースを作成しましたLocalCacheFile。あなたが思うようにすべてが機能します。このための Xaml コードは次のようになります。

<Image Source="{x:Bind imageSource,Converter={StaticResource LocalCacheFile}}" />

ただし、次の問題があります。FallbackValue を使用してimageSourceが空の場合のプレースホルダー イメージを配置しようとすると、奇妙な動作が発生しx:Bindます。

次のコードは、期待どおりに機能します

<Image Source="{Binding imageSource,FallbackValue='ms-appx:///Assets/default.png',Converter={StaticResource LocalCacheFile}}" />

しかし

<Image Source="{x:Bind imageSource,FallbackValue='ms-appx:///Assets/default.png',Converter={StaticResource LocalCacheFile}}" />

ではない!

私はそれを 1 つのコンバーターに分離しましたがDependencyProperty.UnsetValue、x:Bind が処理されていないようです。

TL;DR; これは、テストとして単独で使用すると、同じ誤った動作をトリガーする、私の文字列プレフィックスのコードです。

public class StringPrefix : IValueConverter
{
    public string prefix { get; set; }

    public object Convert(object value, Type typeName, object parameter, string language)
    {
        if (value == DependencyProperty.UnsetValue || value == null || (string)value == "")
            return DependencyProperty.UnsetValue ;

        return (prefix + value.ToString());
    }

    public object ConvertBack(object value, Type typeName, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

上記のコンバーターは、Binding. とともに使用すると、型例外が発生しx:Bindます。

これどうしたの?


編集:例外に関する詳細。

生成されたコードは次のとおりです。

        private void Update_project_imageSource(global::System.String obj, int phase)
        {
            if((phase & ((1 << 0) | NOT_PHASED | DATA_CHANGED)) != 0)
            {
                XamlBindingSetters.Set_Windows_UI_Xaml_Controls_Image_Source(this.obj16, (global::Windows.UI.Xaml.Media.ImageSource)this.LookupConverter("LocalCacheFile").Convert(obj, typeof(global::Windows.UI.Xaml.Media.ImageSource), null, null), null);
            }
        }

例外の詳細:

System.InvalidCastException was unhandled by user code
  HResult=-2147467262
  Message=Unable to cast object of type 'System.__ComObject' to type 'Windows.UI.Xaml.Media.ImageSource'.
  Source=Test
  StackTrace:
       at Test.Pages.ProjectView.ProjectView_obj1_Bindings.Update_project_imageSource(String obj, Int32 phase)
       at Test.Pages.ProjectView.ProjectView_obj1_Bindings.Update_project(Project obj, Int32 phase)
       at Test.Pages.ProjectView.ProjectView_obj1_Bindings.Update_(ProjectView obj, Int32 phase)
       at Test.Pages.ProjectView.ProjectView_obj1_Bindings.Update()
       at Test.Pages.ProjectView.<.ctor>b__6_0(FrameworkElement s, DataContextChangedEventArgs e)
  InnerException: 

(私には、生成されたコードがデフォルト値の可能性を扱っていないように見えます。ところで、それ__ComObjectDependencyProperty.UnsetValue.

編集 2 : Convert 関数を DependencyProperty.UnsetValue 関数の代わりに null を返すように変更した場合、それを追加する必要がありますx:Bindが、その後、関数を使用するという期待される仕事x:Bindも実行しませんBindingFallbackValue

4

2 に答える 2

7

FallbackValueとはBinding別物x:Bindです。

ではBindingFallbackValueバインディングが値を返すことができない場合に使用する値です。

Pathがデータ ソース上でまったく評価されない場合、または双方向バインディングを使用してソース上でPathを設定しようとするとデータ バインディング エンジンによってキャッチされる例外がスローされる場合、バインディングはFallbackValueを使用します。FallbackValueは、ソース値が依存関係プロパティのセンチネル値DependencyProperty.UnsetValueである場合にも使用されます。

ただし、x:BindではFallbackValue、ソースまたはパスを解決できない場合に表示する値を指定します。では動作しませんDependencyProperty.UnsetValue

ご存じのとおり、x:Bindはコンパイル時にコードを生成し、厳密に型指定されています。Converterinを使用するx:BindConverter、同じ型の の戻り値がターゲット プロパティと見なされ、コードのようにキャストされます。

(global::Windows.UI.Xaml.Media.ImageSource)this.LookupConverter("LocalCacheFile").Convert(obj, typeof(global::Windows.UI.Xaml.Media.ImageSource), null, null)

に戻るDependencyProperty.UnsetValueと、にキャストできないためConverter、例外がスローされます。DependencyProperty.UnsetValueImageSource

シナリオでは、 を使用できますTargetNullValue

TargetNullValueは、同様のシナリオを持つ同様のプロパティです。違いは、Path と Source が評価される場合にバインディングがTargetNullValueを使用することですが、そこで見つかった値は null です。

たとえば、次のコードを使用すると XAML になります。

<Image Source="{x:Bind imageSource, TargetNullValue='ms-appx:///Assets/default.png', Converter={StaticResource LocalCacheFile}}" />

そして では、代わりに をConvert返します。nullDependencyProperty.UnsetValue

これは、アプリを実行していて、imageSourceが空のときに機能します。しかし、設計時のメリットを得るには、まだ を使用する必要がありますFallbackValue。したがってx:Bind、次のように使用できます。

<Image Source="{x:Bind imageSource, TargetNullValue='ms-appx:///Assets/default.png', FallbackValue='ms-appx:///Assets/default.png', Converter={StaticResource LocalCacheFile}}" />
于 2016-02-05T07:42:15.503 に答える
4

ではx:BindFallBackValue実際には設計時のデータにのみ使用されます。さて、もっと重要なことについて話しましょう。を使用する理由x:Bind。をスピンアップするコストで、それだけの価値があるとIValueConverter確信していますか? x:Bind私は違います。x:Bind開発者がリストの外側のバインディングを正しく処理するのに苦労しているのを見たとき、私の推奨は に切り替えることbindingです。毎回。リスト内では、コンパイルされたバインドには「繰り返し」の値がありますが、他の場所では、努力する価値があることを私に証明する必要があります-そうでなければ難しい場合. 通常x:bindは素晴らしいです。しかし、このような場合や、UpdateSourceTriggerフォールバックやデフォルト設定などの場合bindingはまったく問題ありません。

于 2016-02-07T06:17:20.593 に答える