9

うまくいかないようですのでお願いします。

次のオブジェクトにバインドしていると仮定します。

public class HurrDurr
{
  public string Hurr {get{return null;}}
  public string Durr {get{return null;}}
}

これに対してMultiBindingを使用すると、フォールバック値が表示されるように見えますね。

<TextBlock>
    <TextBlock.Text>                                
        <MultiBinding StringFormat="{}{0} to the {1}"
                        FallbackValue="Not set!  It works as expected!)">
            <Binding Path="Hurr"/>
            <Binding Path="Durr"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

ただし、結果は実際には「から」になります。バインディングを強制的に返すことさえDependencyProperty.UnsetValue機能しません:

<TextBlock xmnlns:base="clr-namespace:System.Windows;assembly=WindowsBase">
    <TextBlock.Text>                                
        <MultiBinding StringFormat="{}{0} to the {1}"
            FallbackValue="Not set!  It works as expected!)">
            <Binding Path="Hurr"
                FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" />
            <Binding Path="Durr"
                FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

TargetNullValueでも同じことを試しましたが、これもずっとバストでした。

したがって、MultiBindingがFallbackValueを使用することは決してないようです。これは本当ですか、それとも私は何かが足りませんか?


もう少しいじってみると、コンバーターが必要なUnsetValueを返すことができることがわかりました。

class MultiValueFailConverter : IMultiValueConverter
{
    public object Convert(
        object[] values, 
        Type targetType, 
        object parameter, 
        System.Globalization.CultureInfo culture)
    {
        if (values == null || 
            values.Length != 2 ||
            values.Any(x=>x == null))
            return System.Windows.DependencyProperty.UnsetValue;
        return values;
    }

    public object[] ConvertBack(
        object value, 
        Type[] targetTypes, 
        object parameter, 
        System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException("Too complex hurt brain.");
    }
}

しかし、これは汚い汚いハックのようです。このようなシナリオは、フレームワークで説明されると思います。しかし、Reflectorには何も見つかりません。

4

1 に答える 1

8

これは少し古い質問ですが、説明が必要な場合があります。

FallbackValueドキュメントから:

次の場合、バインディングは値を正常に返します。

  1. バインディングソースへのパスは正常に解決されます。
  2. 値コンバーターは、もしあれば、結果の値を変換することができます。
  3. 結果の値は、バインディングターゲット(ターゲット)プロパティに対して有効です。

1と2がDependencyProperty.UnsetValueを返す場合、ターゲットプロパティはFallbackValueの値(使用可能な場合)に設定されます。FallbackValueがない場合は、ターゲットプロパティのデフォルト値が使用されます。

提供されている例では、バインディングはHurrおよびDurrプロパティに正常に解決されます。Nullは文字列の有効な値であり、バインディングが有効であることを意味します。

つまり、FallbackValueは、バインディングが値を返すことができず、提供されている例では、バインディングが有効な値を提供している場合に使用されます。

たとえば、元の例に基づいた次の各スニペットを取り上げます。


1HurrプロパティとDurrプロパティは正しくバインドされています。nullは有効な値であり、FallbackValueは表示されません。

<TextBlock>
    <TextBlock.Text>
        <MultiBinding FallbackValue="Binding is valid. I will never be seen." StringFormat="{}{0} to the {1}">
            <Binding Path="Hurr" />
            <Binding Path="Durr" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>


2HurrプロパティとDurrプロパティが正しくバインドされていません。FallbackValueが表示されます。

<TextBlock>
    <TextBlock.Text>
        <MultiBinding FallbackValue="Binding paths are invalid. Look at me." StringFormat="{}{0} to the {1}">
            <Binding Path="xHurr" />
            <Binding Path="xDurr" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>


31つのバインディングパスが無効な場合、FallbackValueが表示されます。

<TextBlock>
    <TextBlock.Text>
        <MultiBinding FallbackValue="One binding path is invalid. Look at me." StringFormat="{}{0} to the {1}">
            <Binding Path="xHurr" />
            <Binding Path="Durr" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

例4
前の例と同様に、バインディングは正しいため、FallbackValueは使用されません。さらに、親の各子BindingプロパティのMultiBindingFallbackValueは、子Bindingではなく、MultiBindingのターゲットプロパティに使用されるFallbackValueを参照する必要があります。

<TextBlock xmlns:base="clr-namespace:System.Windows;assembly=WindowsBase">
    <TextBlock.Text>
        <MultiBinding FallbackValue="Binding is valid. I will never be seen." StringFormat="{}{0} to the {1}">
            <Binding FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" Path="Hurr" />
            <Binding FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" Path="Durr" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

例5バインディングは、バインドされているオブジェクトを使用するため、プロパティ
にパスが指定されていなくても、バインディングは引き続き有効です。Binding

<TextBlock xmlns:base="clr-namespace:System.Windows;assembly=WindowsBase">
    <TextBlock.Text>
        <MultiBinding FallbackValue="Binding is still valid. I will never be seen." StringFormat="{}{0} to the {1}">
            <Binding FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" />
            <Binding FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

例6
最後に、コンバーターをBindingプロパティのいずれかに追加して、UnsetValueを強制すると、MultiBindingFallbackValueが表示されます。

コンバータ

internal class ForceUnsetValueConverter : IValueConverter
{
    #region Implementation of IValueConverter

    public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
    {
        return DependencyProperty.UnsetValue;
    }

    public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
    {
        throw new NotImplementedException();
    }

    #endregion
}

XAML

<TextBlock>
    <TextBlock.Text>
        <MultiBinding FallbackValue="Binding is valid, but look at me. I'm an UnsetValue." StringFormat="{}{0} to the {1}">
            <Binding Converter="{StaticResource ForceUnset}" Path="Hurr" />
            <Binding Path="Durr" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>
于 2013-01-09T20:59:44.937 に答える