2

次のような状況があります。

いくつかの ViewModel オブジェクトがあり、そのうちのいくつかは interface を実装していますが、実装しISomeInterfaceていないものもあります。SomeEnumerationインターフェイスは、 ( )と呼ばれるプロパティを公開しますIEnumerable<T>

例えば:

public sealed class ViewModelA : ViewModelBase, ISomeInterface
{
    // ...

    IEnumerable<Foo> ISomeInterface.SomeEnumeration
    {
        get { ...; }
    }
}

public sealed class ViewModelB : ViewModelBase
{
    // ...
}

私の XAML は、これまでのところ、両方の ViewModel がたまたまバインド対象のプロパティ ( 、 など) を持つように設計されていPropertyAますPropertyB。私がバインドしているプロパティが、DataContext. しかし、今は...そして、明示的に実装されているプロパティに反対します(それがWPFバインディングエンジンに違いをもたらすかどうかはわかりません)。

基本的に、私の xaml は次のようになります。

<StackPanel
  Visiblity="{Binding Path=SomeEnumeration, Converter={StaticResource AnyConverter}">
    ...
</StackPanel>

次の理由により、これが機能するかどうかはわかりません。

  1. すべてDataContextにプロパティが含まれているわけではありません (含まれていない場合は、非表示にする必要があります) ... この場合はどうすればよいですか?
  2. プロパティを含む sについては、DataContext明示的に実装されています...最初にキャストする必要がありますか?
4

2 に答える 2

6

FallbackValue一般に、WPF DataBinding Engine を使用する場合は、およびTargetNullValueバインディング プロパティも利用する必要があります。これらは正確に何をしますか?

FallbackValue: バインディングが値を返すことができない場合の値を取得または設定します。
TargetNullValue: ソースの値がnullの場合にターゲットで使用される値を取得または設定します。

Jon は、この回答でバインド エンジンについてかなりよく説明しています。

Binding.DoNothing は、値コンバーターからアクティブに返すオブジェクト インスタンスです。これは、ターゲット プロパティの値をまったく更新しないようバインディング エンジンに指示します。Josh Smith による、これを何に使用できるかの良い例を次に示します。

FallbackValue はバインディングで設定するプロパティです。次の場合に、ターゲット プロパティに適用する値を指定できます。

  • バインディング ソースを解決できない (バインディング パスが間違っているなど)。
  • バインディング プロパティの値が DependencyProperty.UnsetValue と等しい、または
  • バインディングに使用される値コンバーターが例外をスローする、または
  • バインディングに使用される値コンバーターが DependencyProperty.UnsetValue を返す、または
  • バインディング パイプラインによって生成された値は、ターゲット プロパティに対して有効ではありません (たとえば、型が間違っています)。

TargetNullValue もバインディングで設定するプロパティです。ソース プロパティの値が null の場合に、ターゲット プロパティに適用される値を指定できます。たとえば、テキスト ボックスを文字列プロパティ TargetNullValue にバインドすると、ソース文字列が null の場合にテキスト ボックスに表示される内容を選択できます。


「明示的に実装されたインターフェイス」へのバインドに関する限り、実際の問題は、インターフェイス プロパティへのパスをどのように設定するかということです。そのインターフェイスがどのように実装されているかは重要ではないためです。これは実際には XAML で非常に簡単に実行できます。以下に例を示します。

<TextBox Text="{Binding Path=(local:ISomeInterface.SomeProperty)}" />

したがって、質問に直接答えるには:

  1. 利用FallbackValueします(TargetNullValue必要に応じてオプションで)。たとえば、バインディング エラーのためにバインディング値を解決できない場合は、null を渡します。
  2. Path プロパティをインターフェイスのプロパティにバインドするための正しいパターンを利用します (上記の例を参照)。

XAML の使用法:

<StackPanel Visiblity="{Binding Path=(local:ISomeInterface.SomeEnumeration),
                                Converter={StaticResource AnyConverter},
                                FallbackValue={x:Null}}">
    ...
</StackPanel>

最後の注意: バインディングが早期に失敗した場合、nullFallbackValueはコンバーターに渡される値ではなく、バインディングがプロパティ レベルまたはコンバーター レベルなどで失敗した場合に使用される最終的な値になります。コンバーターは、 nullを渡している間も実行されます。

于 2013-11-19T16:30:52.550 に答える
0

状況に対する迅速かつ適切な修正は、既に配置されているコンバーターにすべてのロジックを配置することです。

xaml : (バインディング)

 <StackPanel
       Visiblity="{Binding Path=., Converter={StaticResource AnyConverter}">
       ...
 </StackPanel>

cs : (あなたのコンバーター)

  Convert()
  {
       return value Is ISomeInterface ? 
              (((ISomeInterface)value).SomeEnumeration == SomeEnumeration.SomeValue ? 
              Visibility.Visible :  Visibility.Collapsed) : Visibility.Collapsed;       
  }
于 2013-11-19T15:43:46.513 に答える