Vi en línea 2 enfoques diferentes para mejorar un IValueConverter. Uno de ellos extendió un ValueConverter desde MarkupExtension, el otro desde DependencyObject. No puedo extenderme de ambos, así que me pregunto si alguien es mejor que el otro.IValueConverter mejorado - ¿MarkupExtension u DependencyObject?
Respuesta
Derivado de cada uno le da diferentes tipos de potencia y flexibilidad:
Derivado
MarkupExtension
le permite utilizar el convertidor de valores sin que sea un recurso estático, como se describe a continuación:public class DoubleMe : MarkupExtension, IValueConverter { public override object ProvideValue(IServiceProvider serviceProvider) { return this; } public object Convert(object value, /*rest of parameters*/) { if (value is int) return (int)(value) * 2; //double it else return value.ToString() + value.ToString(); } //... }
En XAML, puede usarlo directamente sin crear un StaticResource:
<TextBlock Text="{Binding Name, Converter={local:DoubleMe}}"/> <TextBlock Text="{Binding Age, Converter={local:DoubleMe}}"/>
Este código es muy útil cuando se depura, ya que solo puede escribir
local:DebugMe
y luego puede depurar el DataContext del control en el que lo usa.Derivado
DependencyObject
le permite a configurar el convertidor de valores con algunas preferencias de una manera más expresiva, como se describe a continuación:public class TruncateMe : DependencyObject, IValueConverter { public static readonly DependencyProperty MaxLengthProperty = DependencyProperty.Register("MaxLength", typeof(int), typeof(TruncateMe), new PropertyMetadata(100)); public int MaxLength { get { return (int) this.GetValue(MaxLengthProperty); } set { this.SetValue(MaxLengthProperty, value); } } public object Convert(object value, /*rest of parameters*/) { string s = value.ToString(); if (s.Length > MaxLength) return s.Substring(0, MaxLength) + "..."; else return s; } //... }
En XAML, puede utilizar directamente como:
<TextBlock> <TextBlock.Text> <Binding Path="FullDescription"> <Binding.Converter> <local:TruncateMe MaxLength="50"/> </Binding.Converter> </Binding> </TextBlock.Text>
¿Qué hace? Trunca la cadena
FullDescription
si es más de50
caracteres!
@crazyarabian comentó que:
Su declaración "Derivado de DependencyObject le permite configurar el convertidor de valores con algunas preferencias de una manera más expresiva" no es exclusivo de DependencyObject como se puede crear la misma propiedad MaxLength en una MarkupExtension que da como resultado
<TextBlock Text="Binding Age, Converter={local:DoubleMe, MaxLength=50}}"/>
. Yo diría que una MarkupExtension es más expresiva y menos detallada.
Eso es cierto. Pero eso no es vinculable; es decir, cuando se derivan de MarkupExtension
, entonces no se puede hacer:
MaxLength="{Binding TextLength}"
Pero si usted deriva su convertidor de DependencyObject
, a continuación, puede hacer lo anterior. En ese sentido, es más expresivo en comparación con MarkupExtension
.
Tenga en cuenta que la propiedad de destino debe ser DependencyProperty
para Binding
para que funcione.MSDN says,
Cada unión tiene típicamente estos cuatro componentes: un objeto de unión a la diana , una propiedad objetivo, un origen de enlace, y un camino para el valor en el origen de enlace de usar. Por ejemplo, si se desea enlazar el contenido de un cuadro de texto de la propiedad Name de un objeto empleado, su objeto de destino es del cuadro de texto, la propiedad objetivo la propiedad Text, el valor a utilizar es Nombre y el objeto de origen es el objeto de empleado .
La propiedad de destino debe ser una propiedad de dependencia.
Vi el proyecto Converters de Kent Boogaart en Codeplex extendiendo todos los IValueConverter que escribió desde DependencyObject. http://wpfconverters.codeplex.com/SourceControl/changeset/view/61942# – michael
@Nawaz Su afirmación "Derivar de' DependencyObject' le permite configurar el convertidor de valores con algunas preferencias de una manera más expresiva "no es exclusivo de 'DependencyObject' ya que puede crear la misma propiedad' MaxLength' en '' MarkupExtension' que da como resultado '
@crazyarabian: Sí. Puedes hacer eso, pero eso no es vinculable. No puede hacer 'MaxLength =" {Binding TextLength} "'. – Nawaz
Ya que es my library que estás citando como ejemplo de convertidores que se extienden DependencyObject
, creo que es apropiado para explicar yo.
De hecho, comencé simplemente implementando IValueConverter
con Object
como mi clase base. La única razón por la que cambié a la extensión DependencyObject
fue para permitir una técnica, iniciada por Josh Smith, llamada , bifurcación virtual. Puede leer sobre esa técnica here.
Suponga que quiere hacer algo como esto:
<UserControl.Resources>
<con:CaseConverter Casing="{Binding SomeProperty}"/>
</UserControl.Resources>
esto no funcionará porque los recursos no son parte del árbol visual, por lo que la unión se producirá un error. La bifurcación virtual ataca este pequeño dilema, permitiéndote realizar tal enlace. Sin embargo, todavía se basa, al igual que cualquier otra vinculación de WPF, en que el objetivo sea DependencyObject
. Por lo tanto, si simplemente implementé IValueConverter
sin extender DependencyObject
, no podrá utilizar ramas virtuales.
Ahora, si soy completamente honesto, no estoy seguro de que todavía haría esto si tuviera mi tiempo de nuevo. Nunca en realidad tenía para usar una rama virtual, solo quería habilitar el escenario. Incluso puedo cambiar esto en una versión futura de mi biblioteca. Así que mi consejo sería adherirse a una clase base de Object
(o un simple derivado de la misma) a menos que realmente piense que necesitará una bifurcación virtual.
¿Funcionará esto en Silverlight también? – Shimmy
- 1. Utilice IValueConverter con DynamicResource?
- 2. MarkupExtension con parámetros de enlace
- 3. IValueConverter con Bound Dependency Properties
- 4. VS2010 Custom MarkupExtension
- 5. WPF: IValueConverter unidireccional
- 6. DepedencyProperty dentro de una MarkupExtension
- 7. IValueConverter no funciona para SolidColorBrush
- 8. ¿Se ha mejorado Soundex?
- 9. TransactionScope: ¿Ha mejorado?
- 10. Uso de un IValueConverter genérico de XAML
- 11. ¿Cómo se implementa DependencyObject de WPF?
- 12. Comprobación nula en un bucle forzado mejorado
- 13. ¿Hay un intérprete toploop mejorado para OCaml?
- 14. Facebook mejorado Auth Dialog Button Tipos
- 15. Excepción: Tipo 'IValueConverter' no tener un TypeConverter pública clase
- 16. usando IValueConverter con DataContext actual en enlace bidireccional
- 17. ¿Cómo se pasan datos a un IValueConverter en XAML?
- 18. Debe crear DependencySource en el mismo hilo que DependencyObject
- 19. ¿Qué uso tiene DependencyProperty cuyo ownerType no es DependencyObject?
- 20. ¿Es posible obtener x: Nombre de un DependencyObject (Silverlight)?
- 21. cómo implementar el manejo de sesión mejorado en PHP
- 22. Última iteración del bucle for mejorado en java
- 23. Tengo un método no mejorado, ¿cómo puedo mejorar su eficiencia?
- 24. ¿Mejorado "ls" con información de estado de git?
- 25. No se ha mejorado, pero es superClass [clase play.db.ebean.Model] es?
- 26. ¿De qué sirve `-u` en 'git push -u origin master`?
- 27. Emacs revert-buff (s-u): ¿qué es s-u?
- 28. WebBrowser.DrawToBitmap() u otros métodos?
- 29. Python, PowerShell u otro?
- 30. Significado del sufijo U
Supongo que depende de lo que está tratando de lograr. ¿Puedes agregar más detalles? –