Próbuję napisać markupextension takiego:Czy TypeConverter być stosowany do argumentu konstruktora
[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;
}
}
Aby być stosowany tak:
<Label Content="{units:Length 1 mm}" />
błądzi z:
TypConverter dla typu "Długość" nie obsługuje konwersji z łańcucha.
TypeConverter działa jeśli:
- Umieścić go na własność
Value
i mieć domyślny konstruktor. - Udekoruj typ
Length
za pomocą atrybutu.
Chociaż może to być x/y Nie chcę żadnego z tych rozwiązań.
Oto kod dla przetwornika:
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);
}
}
Dziękuję panu, nie udało mi się googlować. Czy zdajesz sobie sprawę z tego, jak wiele niejawnej konwersji, która powoduje zastosowanie atrybutu do definicji klasy? Może to kolejne pytanie. A może [czat] (http://chat.stackoverflow.com/rooms/18165/wpf) –
Nie jestem pewien, co oznacza "jak wiele niejawnej konwersji". Ale jeśli zastosujesz atrybut do typu Długość, konwersja będzie miała miejsce za każdym razem, gdy ustawisz Długość w XAML. – Clemens
Włącza również powiązania. Może rzeczy takie jak serializacja. Nie jestem wielkim fanem niejawnej konwersji :) –