programing

바인딩 변환기 매개 변수

yellowcard 2023. 4. 10. 21:32
반응형

바인딩 변환기 매개 변수

내가 이걸 할 수 있는 방법이 있을까?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내 컨버터 클래스에도 적응할 수 있어

ConverterParameter종속 속성이 아니므로 속성을 바인딩할 수 없습니다.

부터Binding에서 파생되지 않았습니다.DependencyObject해당 속성은 종속성 속성이 될 수 없습니다.따라서 바인딩은 다른 바인딩의 대상 개체가 될 수 없습니다.

하지만 다른 해결책이 있습니다.를 일반 바인딩 대신 다중 값 변환기와 함께 사용할 수 있습니다.

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

아니요, 안타깝게도 이 작업은 불가능합니다.ConverterParameter이 아니다DependencyProperty바인딩을 사용할 수 없게 됩니다.

하지만 아마 당신은 속임수를 써서MultiBinding와 함께IMultiValueConverter2번 홀에 합격하다Tag특성.

다른 방법으로 사용할 수도 있습니다.MarkupExtension사용하기 위해서Binding잠깐 동안ConverterParameter이 솔루션에서는 디폴트를 사용할 수 있습니다.IValueConverter대신IMultiValueConverter왜냐하면ConverterParameter에 전달됩니다.IValueConverter첫 번째 샘플에서 기대했던 것처럼요.

여기 재사용할 수 있는 것이 있습니다.MarkupExtension:

/// <summary>
///     <example>
///         <TextBox>
///             <TextBox.Text>
///                 <wpfAdditions:ConverterBindableParameter Binding="{Binding FirstName}"
///                     Converter="{StaticResource TestValueConverter}"
///                     ConverterParameter="{Binding ConcatSign}" />
///             </TextBox.Text>
///         </TextBox>
///     </example>
/// </summary>
[ContentProperty(nameof(Binding))]
public class ConverterBindableParameter : MarkupExtension
{
    #region Public Properties

    public Binding Binding { get; set; }
    public BindingMode Mode { get; set; }
    public IValueConverter Converter { get; set; }
    public Binding ConverterParameter { get; set; }

    #endregion

    public ConverterBindableParameter()
    { }

    public ConverterBindableParameter(string path)
    {
        Binding = new Binding(path);
    }

    public ConverterBindableParameter(Binding binding)
    {
        Binding = binding;
    }

    #region Overridden Methods

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var multiBinding = new MultiBinding();
        Binding.Mode = Mode;
        multiBinding.Bindings.Add(Binding);
        if (ConverterParameter != null)
        {
            ConverterParameter.Mode = BindingMode.OneWay;
            multiBinding.Bindings.Add(ConverterParameter);
        }
        var adapter = new MultiValueConverterAdapter
        {
            Converter = Converter
        };
        multiBinding.Converter = adapter;
        return multiBinding.ProvideValue(serviceProvider);
    }

    #endregion

    [ContentProperty(nameof(Converter))]
    private class MultiValueConverterAdapter : IMultiValueConverter
    {
        public IValueConverter Converter { get; set; }

        private object lastParameter;

        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (Converter == null) return values[0]; // Required for VS design-time
            if (values.Length > 1) lastParameter = values[1];
            return Converter.Convert(values[0], targetType, lastParameter, culture);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            if (Converter == null) return new object[] { value }; // Required for VS design-time

            return new object[] { Converter.ConvertBack(value, targetTypes[0], lastParameter, culture) };
        }
    }
}

이와 함께.MarkupExtension코드 베이스에서는, 간단하게 바인드 할 수 있습니다.ConverterParameter다음과 같이 합니다.

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

첫 번째 제안서랑 비슷하네요

언급URL : https://stackoverflow.com/questions/15309008/binding-converterparameter

반응형