web-dev-qa-db-fra.com

Liaison ConverterParameter

Est-il possible de faire cela dans un 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>

J'ai simplement besoin d'envoyer la Tag du parent de niveau supérieur et la Tag du contrôle lui-même à ma classe de convertisseur.

141
dotNET

La propriété ConverterParameter ne peut pas être liée car il ne s'agit pas d'une propriété de dépendance.

Puisque Binding n'est pas dérivé de DependencyObject, aucune de ses propriétés ne peut être une propriété de dépendance. En conséquence, une liaison ne peut jamais être l'objet cible d'une autre liaison.

Il existe cependant une solution alternative. Vous pouvez utiliser un MultiBinding avec un convertisseur multi-valeur au lieu d'un Reliure normale:

<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>

Le convertisseur multivaleur obtient un tableau de valeurs source en entrée:

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();
    }
}
271
Clemens

Non, malheureusement, cela ne sera pas possible car ConverterParameter n'est pas un DependencyProperty, vous ne pourrez donc pas utiliser de liaisons.

Mais peut-être pourriez-vous tricher et utiliser un MultiBinding avec IMultiValueConverter pour transmettre les propriétés 2 Tag.

33
sa_ddam213

Il existe également une autre façon d'utiliser MarkupExtension afin d'utiliser Binding pour un paramètre de convertisseur. Avec cette solution, vous pouvez toujours utiliser le convertisseur IValueConverter par défaut à la place du convertisseur IMultiValueConverter car le paramètre ConverterParameter est transmis au convertisseur IValueConverter exactement comme vous le souhaitiez dans votre premier échantillon.

Voici mon MarkupExtension réutilisable:

/// <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
}

Avec cette extension dans votre base de code, vous pouvez simplement lier le paramètre de convertisseur de la manière suivante:

<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>

Qui ressemble presque à votre proposition initiale

6
Pascalsz