web-dev-qa-db-ja.com

バインディングコンバーターパラメーター

Styleでこれを行う方法はありますか?

<Style TargetType="FrameworkElement">
    <Setter Property="Visibility">
        <Setter.Value>
            <Binding Path="Tag"
                RelativeSource="{RelativeSource AncestorType=UserControl}"
                Converter="{StaticResource AccessLevelToVisibilityConverter}"
                ConverterParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Tag}" />                        
        </Setter.Value>
    </Setter>
</Style>

トップレベルの親のTagとコントロール自体のTagをコンバータークラスに送信するだけです。

140
dotNET

ConverterParameterプロパティは、依存関係プロパティではないためバインドできません。

BindingDependencyObjectから派生したものではないため、そのプロパティは依存関係プロパティになりません。結果として、Bindingが別のBindingのターゲットオブジェクトになることはありません。

ただし、代替ソリューションがあります。通常のバインディングの代わりに MultiBinding複数値コンバーター とともに使用できます。

<Style TargetType="FrameworkElement">
    <Setter Property="Visibility">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource AccessLevelToVisibilityConverter}">
                <Binding Path="Tag" RelativeSource="{RelativeSource Mode=FindAncestor,
                                                     AncestorType=UserControl}"/>
                <Binding Path="Tag" RelativeSource="{RelativeSource Mode=Self}"/>
            </MultiBinding>
        </Setter.Value>
    </Setter>
</Style>

複数値コンバーターは、入力としてソース値の配列を取得します。

public class AccessLevelToVisibilityConverter : IMultiValueConverter
{
    public object Convert(
        object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values.All(v => (v is bool && (bool)v))
            ? Visibility.Visible
            : Visibility.Hidden;
    }

    public object[] ConvertBack(
        object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
268
Clemens

いいえ、残念ながら、ConverterParameterDependencyPropertyではないため、これはできません。したがって、バインディングを使用することはできません。

しかし、2つのMultiBindingプロパティを渡すために、IMultiValueConverterTagをチートして使用することもできます。

33
sa_ddam213

コンバーターパラメーターにバインドを使用するために、MarkupExtensionを使用する別の方法もあります。このソリューションでは、最初のサンプルで期待したようにConverterParameterがIValueConverterに渡されるため、IMultiValueConverterの代わりにデフォルトのIValueConverterを使用できます。

再利用可能なMarkupExtensionは次のとおりです。

/// <summary>
///     <example>
///         <TextBox>
///             <TextBox.Text>
///                 <wpfAdditions:ConverterBindableParameter Binding="{Binding FirstName}"
///                     Converter="{StaticResource TestValueConverter}"
///                     ConverterParameterBinding="{Binding ConcatSign}" />
///             </TextBox.Text>
///         </TextBox>
///     </example>
/// </summary>
public class ConverterBindableParameter : MarkupExtension
{
    #region Public Properties

    public Binding Binding { get; set; }

    public IValueConverter Converter { get; set; }

    public Binding ConverterParameterBinding { get; set; }

    #endregion

    #region Overridden Methods

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var multiBinding = new MultiBinding();
        multiBinding.Bindings.Add(Binding);
        multiBinding.Bindings.Add(ConverterParameterBinding);
        var adapter = new MultiValueConverterAdapter
                      {
                          Converter = Converter
                      };
        multiBinding.Converter = adapter;
        return multiBinding.ProvideValue(serviceProvider);
    }

    #endregion
}

コードベースでこの拡張機能を使用すると、コンバータパラメータを次の方法で簡単にバインドできます。

<Style TargetType="FrameworkElement">
<Setter Property="Visibility">
    <Setter.Value>
     <wpfAdditions:ConverterBindableParameter Binding="{Binding Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}"
                 Converter="{StaticResource AccessLevelToVisibilityConverter}"
                 ConverterParameterBinding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Tag}" />          
    </Setter.Value>
</Setter>

Wichは最初の提案のように見えます

5
Pascalsz