2016-01-28 8 views
5

मैं इस तरह एक markupextension लिखने के लिए कोशिश कर रहा हूँ: साथएक TypeConverter निर्माता तर्क के लिए इस्तेमाल किया जा सकता

<Label Content="{units:Length 1 mm}" /> 

errs:

[MarkupExtensionReturnType(typeof(Length))] 
public class LengthExtension : MarkupExtension 
{ 
    // adding the attribute like this compiles but does nothing. 
    public LengthExtension([TypeConverter(typeof(LengthTypeConverter))]Length value) 
    { 
     this.Value = value; 
    } 

    [ConstructorArgument("value")] 
    public Length Value { get; set; } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return this.Value; 
    } 
} 

इस तरह इस्तेमाल किया जा करने के लिए

प्रकार "लंबाई" के लिए टाइप कनवर्टर स्ट्रिंग से कनवर्ट करने का समर्थन नहीं करता है।

TypeConverter काम करता है अगर मैं:

  • Value संपत्ति पर रखो और एक डिफ़ॉल्ट ctor है।
  • विशेषता के साथ Length प्रकार सजाने।

हालांकि यह x/y हो सकता है, मैं उन समाधानों में से कोई भी नहीं चाहता हूं।

public class LengthTypeConverter : TypeConverter 
{ 
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
    { 
     if (sourceType == typeof(string)) 
     { 
      return true; 
     } 

     return base.CanConvertFrom(context, sourceType); 
    } 

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 
    { 
     if (destinationType == typeof(InstanceDescriptor) || destinationType == typeof(string)) 
     { 
      return true; 
     } 

     return base.CanConvertTo(context, destinationType); 
    } 

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 
    { 
     var text = value as string; 
     if (text != null) 
     { 
      return Length.Parse(text, culture); 
     } 

     return base.ConvertFrom(context, culture, value); 
    } 

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 
    { 
     if (value is Length && destinationType != null) 
     { 
      var length = (Length)value; 
      if (destinationType == typeof(string)) 
      { 
       return length.ToString(culture); 
      } 
      else if (destinationType == typeof(InstanceDescriptor)) 
      { 
       var factoryMethod = typeof(Length).GetMethod(nameof(Length.FromMetres), BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(double) }, null); 
       if (factoryMethod != null) 
       { 
        var args = new object[] { length.metres }; 
        return new InstanceDescriptor(factoryMethod, args); 
       } 
      } 
     } 

     return base.ConvertTo(context, culture, value, destinationType); 
    } 
} 

उत्तर

3

MSDN, Applying the TypeConverterAttribute (जोर मेरा) से:

अपने कस्टम प्रकार कनवर्टर के लिए आदेश में अभिनय प्रकार के रूप में प्रयोग की जाने वाली एक XAML प्रोसेसर के द्वारा एक कस्टम वर्ग के लिए कनवर्टर, आप .नेट फ्रेमवर्क लागू करना चाहिए अपने वर्ग परिभाषा ... को TypeConverterAttribute विशेषता

और

आप प्रति-संपत्ति के आधार पर एक प्रकार कनवर्टर भी प्रदान कर सकते हैं। इसके बजाय एक .नेट फ्रेमवर्क लागू करने की वर्ग परिभाषा के TypeConverterAttribute विशेषता है, यह एक संपत्ति परिभाषा पर लागू होते हैं ...

विशेषता लागू करें किसी अन्य जगह का कोई उल्लेख नहीं। तो आपके प्रश्न का उत्तर

नहीं, एक टाइप कनवर्टर का उपयोग कन्स्ट्रक्टर तर्क के लिए नहीं किया जा सकता है।

+0

धन्यवाद सर, मैं गुगलिंग में विफल रहता हूं। क्या आपको पता है कि वर्ग परिभाषा के कारणों को विशेषता लागू करने में कितना अंतर्निहित रूपांतरण है? शायद यह एक और सवाल है। या शायद [चैट] (http://chat.stackoverflow.com/rooms/18165/wpf) –

+0

सुनिश्चित नहीं है कि "कितना अंतर्निहित रूपांतरण" वास्तव में है। लेकिन यदि आप लंबाई प्रकार में विशेषता लागू करते हैं, तो जब भी आप एक्सएएमएल में लंबाई निर्धारित करते हैं तो रूपांतरण होगा। – Clemens

+0

बाइंडिंग को चालू करता है इसका भी उपयोग करता है। शायद serialization की तरह सामान। मैं निहित रूपांतरण का एक बड़ा प्रशंसक नहीं हूँ :) –

2

आलोचना के लिए इस पोस्ट कर रहा है:

यहाँ कनवर्टर के लिए कोड है

[MarkupExtensionReturnType(typeof(Length))] 
public class LengthExtension : MarkupExtension 
{ 
    public LengthExtension(string value) 
    { 
     this.Value = Length.Parse(value, CultureInfo.InvariantCulture); 
    } 

    public Length Value { get; private set; } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return this.Value; 
    } 
} 

यह काम करता है लेकिन के बारे में अगर कोई कमियां हैं मुझे यकीन है कि नहीं हूँ।

संबंधित मुद्दे

 संबंधित मुद्दे