वहाँ XAML में कई मूल्य कन्वर्टर्स श्रृंखला के लिए एक रास्ता है?


123

मुझे एक स्थिति मिली है जिसमें मुझे एक पूर्णांक मान दिखाने की जरूरत है, जो मेरे डेटा संदर्भ पर एक संपत्ति के लिए बाध्य है, इसे दो बार वार्तालाप के माध्यम से डालने के बाद:

  1. किसी श्रेणी के भीतर मान को उल्टा करें (जैसे श्रेणी 1 से 100 है; डेटाकोटेक्स्ट में मूल्य 90 है; उपयोगकर्ता 10 का मूल्य देखता है)
  2. संख्या को एक स्ट्रिंग में बदलें

मुझे लगता है कि मैं अपने स्वयं के कनवर्टर (कि IValueConverter लागू करता है) बनाकर दोनों कदम उठा सकता हूं। हालाँकि, मुझे पहले से ही एक अलग मूल्य कनवर्टर मिल गया है जो सिर्फ पहला कदम रखता है, और दूसरा चरण Int32Converter द्वारा कवर किया गया है।

क्या ऐसा कोई तरीका है जिससे मैं XAML में इन दो मौजूदा वर्गों को श्रृंखलाबद्ध कर सकता हूं और बिना एक और वर्ग बनाए जो उन्हें एकत्र करता है?

अगर मुझे इसमें से किसी को स्पष्ट करने की आवश्यकता है, तो कृपया मुझे बताएं। :)

धन्यवाद।

जवाबों:


198

मैंने अपने सिल्वरलाइट प्रोजेक्ट में गैरेथ इवांस द्वारा इस पद्धति का उपयोग किया ।

यहाँ मेरा यह कार्यान्वयन है:

public class ValueConverterGroup : List<IValueConverter>, IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return this.Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
    }

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

    #endregion
}

जो तब XAML में इस तरह से इस्तेमाल किया जा सकता है:

<c:ValueConverterGroup x:Key="InvertAndVisibilitate">
   <c:BooleanInverterConverter/>
   <c:BooleanToVisibilityConverter/>
</c:ValueConverterGroup>

3
क्या यह सबसे अच्छा है, ConvertBack के कार्यान्वयन के लिए संग्रह की एक प्रति बनाने और उसे उल्टा करने के लिए, और फिर उस पर एकत्र होना चाहिए? तो ConvertBack होगाreturn this.Reverse<IValueConverter>().Aggregate(value, (current, converter) => converter.ConvertBack(current, targetType, parameter, culture));
निक

5
@DLeh यह वास्तव में सुरुचिपूर्ण नहीं है क्योंकि यह काम नहीं करता है। यह सही लक्ष्य प्रकार के बजाय अंतिम लक्ष्य प्रकार के साथ सभी कन्वर्टर्स प्रदान करता है ...
अलेक्जेंडर टॉपलेक

मैं पहले कन्वर्टर के रूप में एक मल्टीव्यूऑन चार्जर के साथ इसका उपयोग कैसे कर सकता हूं?
लाइटमोंक

1
@ एयरपोर्ट एक सहकर्मी को बस यह सवाल लगा और उसने मुझे फिर से देख लिया, उदासीनता के कारण। केवल, मैंने देखा कि आप क्रेडिट नहीं पा रहे थे जिसके आप हकदार थे (मैंने अपना उत्तर स्वीकार कर लिया है !), इसलिए मैंने अब आपके उत्तर को मान लिया है। केवल 9 साल की देरी के बारे में ...: facepalm:
Mal Ross

@MalRoss हाहा! धन्यवाद! यह सुनने में अच्छा है कि यह अभी भी उपयोगी है, मैंने सिल्वरलाइट को अब तक लगभग 8 वर्षों तक नहीं छुआ है और फिर भी यह अभी भी मेरा सबसे लोकप्रिय उत्तर है :)
टाउन

54

जोश स्मिथ के सौजन्य से मुझे वही मिला, जो पाइपिंग वैल्यू कन्वर्टर्स (आर्काइव.ऑर्ग लिंक) का था

वह एक ValueConverterGroupवर्ग को परिभाषित करता है , जिसका एक्सएएमएल में उपयोग वैसा ही है जैसा मैं उम्मीद कर रहा था। यहाँ एक उदाहरण है:

<!-- Converts the Status attribute text to a SolidColorBrush used to draw 
     the output of statusDisplayNameGroup. -->
<local:ValueConverterGroup x:Key="statusForegroundGroup">
  <local:IntegerStringToProcessingStateConverter  />
  <local:ProcessingStateToColorConverter />
  <local:ColorToSolidColorBrushConverter />
</local:ValueConverterGroup> 

उत्तम सामग्री। धन्यवाद, जोश। :)


2
इस समाधान में, प्रत्येक कनवर्टर को केवल एक प्रकार से निपटना होगा (इसे एकल-वैल्यू-कंवर्जन-विशेषता में घोषित किया जाना चाहिए)। @ एयरपोर्ट सॉल्यूशन मल्टीकोवर्टर से भी निपट सकता है।
वाई। शोहम

9
कृपया कार्यान्वयन पोस्ट करें; अन्यथा, लिंकरोट
जेक बर्गर

9

टाउन के कार्यान्वयन की गैरेथ इवांस के सिल्वरलाइट परियोजना , बहुत अच्छा है, लेकिन यह अलग कनवर्टर मानकों का समर्थन नहीं करता।

मैंने इसे संशोधित किया है ताकि आप पैरामीटर प्रदान कर सकें, अल्पविराम सीमांकित (जब तक आप निश्चित रूप से उनसे बच नहीं जाते)।

कनवर्टर:

public class ValueConverterGroup : List<IValueConverter>, IValueConverter
{
    private string[] _parameters;

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if(parameter != null)
            _parameters = Regex.Split(parameter.ToString(), @"(?<!\\),");

        return (this).Aggregate(value, (current, converter) => converter.Convert(current, targetType, GetParameter(converter), culture));
    }

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

    private string GetParameter(IValueConverter converter)
    {
        if (_parameters == null)
            return null;

        var index = IndexOf(converter as IValueConverter);
        string parameter;

        try
        {
            parameter = _parameters[index];
        }

        catch (IndexOutOfRangeException ex)
        {
            parameter = null;
        }

        if (parameter != null)
            parameter = Regex.Unescape(parameter);

        return parameter;
    }
}

नोट: ConvertBack यहाँ लागू नहीं है, मेरे को देखने के सार पूर्ण संस्करण के लिए।

कार्यान्वयन:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:converters="clr-namespace:ATXF.Converters;assembly=ATXF" x:Class="ATXF.TestPage">
  <ResourceDictionary>
    <converters:ValueConverterGroup x:Key="converters">
      <converters:ConverterOne />
      <converters:ConverterTwo />
    </converters:ValueConverterGroup>
  </ResourceDictionary>

  <Label Text="{Binding InitialValue, Converter={StaticResource converters}, ConverterParameter='Parameter1,Parameter2'}" />
</ContentPage>

6

हां, चेन कन्वर्टर्स के तरीके हैं, लेकिन यह सुंदर नहीं दिखता है और आपको यहां इसकी आवश्यकता नहीं है। अगर आपको कभी इसकी जरूरत पड़े, तो खुद से पूछें कि क्या वास्तव में जाने का रास्ता है? सरल हमेशा बेहतर काम करता है भले ही आपको अपना स्वयं का कनवर्टर लिखना पड़े।

आपके विशेष मामले में, आपको बस एक स्ट्रिंग में परिवर्तित मूल्य को प्रारूपित करना होगा। StringFormatएक पर संपत्ति Bindingअपने दोस्त यहाँ है।

 <TextBlock Text="{Binding Value,Converter={StaticResource myConverter},StringFormat=D}" />

5
यदि आप बड़े पैमाने पर बाइंडिंग का उपयोग करते हैं, तो चेन कन्वर्टर्स के लिए कस्टम कन्वर्टर लिखना सभी प्रकार के कॉन्फ़िगरेशन के लिए डंब कन्वर्टर्स के टन के साथ समाप्त होता है। उस मामले में स्वीकृत उत्तर एक अद्भुत समाधान है।
जसक गोर्गो

0

बहु-बंधन का समर्थन करने के लिए टाउन के जवाब का एक छोटा विस्तार यहाँ दिया गया है:

public class ValueConverterGroup : List<IValueConverter>, IValueConverter, IMultiValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return this.Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
    }

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

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return Convert(values as object, targetType, parameter, culture);
    }

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

    #endregion
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.