বাইন্ডিং কনভার্টারপ্যারামিটার


165

আমি এখানে এটি করার কোনও উপায় আছে 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নিয়ন্ত্রণের স্বয়ং পাঠাতে হবে।

উত্তর:


303

ConverterParameterসম্পত্তি আবদ্ধ হতে পারে না কারণ এটি একটি নির্ভরতা সম্পত্তি নয়।

যেহেতু এর বৈশিষ্ট্যগুলির Bindingকোনওটিই থেকে প্রাপ্ত নয় DependencyObjectএটি নির্ভরতা বৈশিষ্ট্য হতে পারে। ফলস্বরূপ, একটি বাইন্ডিং কখনই অন্য বাইন্ডিংয়ের টার্গেট অবজেক্ট হতে পারে না।

বিকল্প বিকল্প আছে। আপনি একটি ব্যবহার করতে পারে 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();
    }
}

36

না, দুর্ভাগ্যক্রমে এটি সম্ভব হবে না কারণ ConverterParameterএটি এমন নয় DependencyPropertyযাতে আপনি বাইন্ডিংগুলি ব্যবহার করতে পারবেন না

তবে সম্ভবত আপনি 2 টি বৈশিষ্ট্যে পাস MultiBindingকরার IMultiValueConverterজন্য প্রতারণা করতে এবং ব্যবহার করতে পারেন Tag


13

MarkupExtensionব্যবহারের Bindingজন্য বিকল্প উপায়ও রয়েছে ConverterParameter। এই সমাধানের সাহায্যে আপনি এখনও এর IValueConverterপরিবর্তে ডিফল্টটি ব্যবহার করতে পারেন IMultiValueConverterকারণ আপনার প্রথম নমুনায় আপনি যেমন আশা ConverterParameterকরেছিলেন IValueConverterঠিক তেমনটিই চলে গেছে ।

এখানে আমার পুনরায় ব্যবহারযোগ্য MarkupExtension:

/// <summary>
///     <example>
///         <TextBox>
///             <TextBox.Text>
///                 <wpfAdditions:ConverterBindableParameter Binding="{Binding FirstName}"
///                     Converter="{StaticResource TestValueConverter}"
///                     ConverterParameterBinding="{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>

যা দেখতে প্রায় আপনার প্রাথমিক প্রস্তাব মত মনে হচ্ছে।


4
এটি দরকারী। তবে MultiValueConverterAdapterনিখোঁজ। আমি এটি এখানে খুঁজে পেয়েছি ।
blearyeye
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.