WPF en comparación con Xamarin.Forms: semejanzas y diferencias
Plantillas de control
WPF admite el concepto de plantillas de control que proporcionan las instrucciones de visualización de un control (Button
, ListBox
, etc.). Como se mencionó anteriormente, Xamarin.Forms usa clases de representación concretas para esto, las cuales interactúan con la plataforma nativa (iOS, Android, etc.) para visualizar el control.
Sin embargo, Xamarin.Forms tiene un tipo ControlTemplate
que se usa para crear temas de objetos Page
. Proporciona una definición de un objeto Page
que proporciona contenido coherente, pero permite al usuario de la página cambiar colores, fuentes, etc., e incluso agregar elementos para que sea único para la aplicación.
Esto se usa habitualmente para crear cuadros de diálogo de autenticación y solicitudes de confirmación, y para proporcionar una apariencia de página normalizada, pero que se puede personalizar dentro de la aplicación. Como parte de esta compatibilidad, se usan muchos controles conocidos con nombre de WPF:
ContentPage
ContentView
ContentPresenter
TemplateBinding
Pero es importante saber que estos no sirven para el mismo propósito en Xamarin.Forms. Para más información sobre esta característica, consulte la página de documentación.
XAML
XAML se usa como lenguaje de marcado declarativo para WPF y Xamarin.Forms. En la mayor parte, la sintaxis es idéntica: la diferencia principal es que los objetos se definen o crean mediante los grafos XAML.
Xamarin.Forms admite la especificación XAML 2009; esto facilita la definición de datos como objetos
string
,int
, etc., así como la definición de tipos genéricos y el envío de argumentos a constructores.Actualmente, no hay ninguna manera de cargar XAML dinámicamente como lo hace WPF con
XamlReader
. Sin embargo, puede obtener la misma funcionalidad básica con un paquete NuGet.
Extensiones de marcado
Xamarin.Forms admite la extensión de XAML a través de extensiones de marcado, de forma parecida a como lo hace WPF. De serie, tiene los mismos bloques de creación básicos:
{x:Array}
{Binding}
{DynamicResource}
{x:Null}
{x:Static}
{StaticResource}
{x:Type}
Además, incluye {x:Reference}
de la especificación XAML 2009 y una extensión de marcado {TemplateBinding}
que se usa para la versión especializada de ControlTemplate
compatible con Xamarin.Forms.
Advertencia
La compatibilidad con ControlTemplate
no es la misma, aunque tenga el mismo nombre.
Xamarin.Forms también admite extensiones de marcado personalizadas, pero la implementación es ligeramente diferente. En WPF, debe efectuar la derivación desde MarkupExtension
: una clase base abstracta. En Xamarin.Forms, esto se reemplaza por una interfaz IMarkupExtension
o IMarkupExtension<T>
que es más flexible.
Al igual que WPF, el único método necesario es un método ProvideValue
que devuelva el valor de la extensión de marcado.
Infraestructura de enlace
Uno de los conceptos básicos que se llevan a cabo es una infraestructura de enlace de datos que permite conectar las propiedades visuales con las propiedades de datos de .NET. Esto permite patrones arquitectónicos como MVVM. El diseño básico es idéntico: tiene una clase base enlazable, BindableObject, que en WPF es la clase DependencyObject. Esta clase base se usa como antecesor raíz para todos los objetos que participarán como destinos en el enlace de datos. A continuación, las clases derivadas exponen objetos BindableProperty que actúan como almacenamiento de respaldo de los valores de propiedad (estos se definen como objetos DependencyProperty en WPF).
Definición de propiedades enlazables
La definición de una propiedad enlazable en Xamarin.Forms es la misma que en WPF:
- El objeto se debe derivar de
BindableObject
. - Debe haber un campo estático público de tipo
BindableProperty
declarado para definir la clave de almacenamiento de respaldo de la propiedad. - Debe haber un contenedor de propiedades de instancia pública que use
GetValue
ySetValue
para recuperar y cambiar el valor de las propiedades.
Para obtener un ejemplo completo, consulte Propiedades enlazables en Xamarin.Forms.
Propiedades adjuntas
Las propiedades asociadas son un subconjunto de la propiedad enlazable y funcionan de la misma manera que lo hacen en WPF. La principal diferencia es que el contenedor de propiedades se omite en este caso y se reemplaza por un conjunto de métodos get/set estáticos en la clase propietaria. Para más información, consulte Propiedades asociadas de Xamarin.Forms.
Uso del motor de enlace
El proceso para usar el motor de enlace es el mismo que en WPF. Se puede usar en código subyacente mediante la creación de un objeto Binding
vinculado a un objeto de origen (cualquier tipo de .NET) y un valor de propiedad opcional (si se omite, trata el objeto de origen como la propiedad en sí, al igual que WPF). A continuación, puede usar SetBinding
en cualquier BindableObject
para asociar el enlace a BindableProperty
.
Como alternativa, puedes definir la relación de enlace en XAML mediante BindingExtension
. Tiene los mismos valores básicos que la extensión en WPF.
La compatibilidad con los enlaces y el motor se parecen más a la implementación de Silverlight que a WPF. Faltan varias características que no se implementaron en Xamarin.Forms:
- No hay compatibilidad con las siguientes características de los enlaces:
- BindingGroupName
- BindsDirectlyToSource
- IsAsync
- MultiBinding
- NotifyOnSourceUpdated
- NotifyOnTargetUpdated
- NotifyOnValidationError
- UpdateSourceTrigger
- UpdateSourceExceptionFilter
- ValidatesOnDataErrors
- ValidatesOnExceptions
- ValidationRules collection
- XPath
- XmlNamespaceManager
RelativeSource
No se admiten los enlaces RelativeSource
. En WPF, estos le permiten enlazar a otros elementos visuales definidos en XAML. En Xamarin.Forms, esta misma funcionalidad se puede lograr mediante la extensión de marcado {x:Reference}
. Por ejemplo, suponiendo que tenemos un control con el nombre "otherControl" que tiene una propiedad Text, podemos enlazarlo de esta manera:
WPF
Text={Binding RelativeSource={RelativeSource otherControl}, Path=Text}
Xamarin.Forms
Text={Binding Source={x:Reference otherControl}, Path=Text}
Se puede usar la misma funcionalidad para la característica {RelativeSource Self}
. Sin embargo, no hay compatibilidad con la localización de antecesores por tipo ({RelativeSource FindAncestor}
).
Contexto de enlace
En WPF, puede definir un valor de propiedad DataContext
que representa el origen de enlace predeterminado. Si no se define el origen de un enlace, se usa este valor de propiedad. El valor se hereda en la parte inferior del árbol visual, lo que permite definirlo en un nivel superior y que los elementos secundarios puedan usarlo.
En Xamarin.Forms, la misma característica está disponible, pero el nombre de la propiedad es BindingContext
.
Convertidores de valores
Los convertidores de valores son totalmente compatibles con Xamarin.Forms, al igual que WPF. Se usa la misma forma de interfaz, pero Xamarin.Forms tiene la interfaz definida en el espacio de nombres Xamarin.Forms
.
Modelo-Vista-Modelo de vista
MVVM es totalmente compatible con WPF y Xamarin.Forms.
WPF incluye un RoutedCommand
integrado que se usa en algunas ocasiones; Xamarin.Forms no tiene compatibilidad integrada con comandos más allá de la definición de interfaz de ICommand
. Puede incluir diversos marcos de MVVM para agregar las clases base necesarias para implementar MVVM.
INotifyPropertyChanged e INotifyCollectionChanged
Ambas interfaces son totalmente compatibles con los enlaces de Xamarin.Forms. A diferencia de muchos marcos basados en XAML, las notificaciones de cambio de propiedad se pueden generar en subprocesos en segundo plano en Xamarin.Forms (al igual que WPF) y el motor de enlace pasará correctamente al subproceso de interfaz de usuario.
Además, ambos entornos admiten SynchronizationContext
y async
/await
para realizar una serialización de subprocesos adecuada. WPF incluye la clase Dispatcher
en todos los elementos visuales, Xamarin.Forms tiene un método estático Device.BeginInvokeOnMainThread
que también se puede usar (aunque es preferible usar SynchronizationContext
para la codificación multiplataforma).
- Xamarin.Forms incluye un elemento
ObservableCollection<T>
que admite notificaciones de cambio de colección. - Puede usar
BindingBase.EnableCollectionSynchronization
para habilitar las actualizaciones entre subprocesos de una colección. La API es ligeramente diferente de la variación de WPF, consulte los documentos para obtener los detalles de uso.
Plantillas de datos
Las plantillas de datos se admiten en Xamarin.Forms para personalizar la representación de una fila (celda) ListView
. A diferencia de WPF que puede usar elementos DataTemplate
para cualquier control orientado al contenido, Xamarin.Forms solo los usa actualmente para ListView
. La definición de plantilla se puede definir insertada (asignada a la propiedad ItemTemplate
) o como un recurso de ResourceDictionary
.
Además, no son tan flexibles como su equivalente de WPF.
- El elemento raíz de
DataTemplate
debe ser siempre un objetoViewCell
. - Los desencadenadores de datos son totalmente compatibles con una plantilla de datos, pero deben incluir una propiedad
DataType
que indique el tipo de propiedad a la que está asociado el desencadenador. DataTemplateSelector
también se admite, pero se deriva deDataTemplate
y, por tanto, se asigna directamente a la propiedadItemTemplate
(en lugar de aItemTemplateSelector
como en WPF).
ItemsControl
No hay ningún equivalente integrado a un elemento ItemsControl
en Xamarin.Forms; pero hay uno personalizado para Xamarin.Forms disponible aquí.
Controles de usuario
En WPF, los elementos UserControl
se usan para proporcionar una sección de la interfaz de usuario que tiene un comportamiento asociado. En Xamarin.Forms, usamos ContentView
con el mismo propósito. Ambos admiten el enlace y la inclusión en XAML.
Navegación
WPF incluye un elemento NavigationService
poco utilizado que podría usarse para proporcionar una característica de navegación "similar a la de un explorador". Sin embargo, la mayoría de las aplicaciones no tuvieron en cuenta esto y, en su lugar, usaron elementos Window
diferentes o secciones diferentes de la ventana para mostrar datos.
En los dispositivos telefónicos, las distintas pantallas suelen ser la solución y, por tanto, Xamarin.Forms incluye compatibilidad con varias formas de navegación:
Estilo de navegación | Tipo de página |
---|---|
Basado en pila (inserción o extracción) | NavigationPage |
Maestro y detalles | MasterDetailPage |
Pestañas | TabbedPage |
Deslizar el dedo hacia la izquierda o la derecha | CarouselView |
NavigationPage
es el enfoque más común, y cada página tiene una propiedad Navigation
que se puede usar para insertar o extraer páginas de la pila de navegación. Esta es la clase equivalente más cercana a NavigationService
que se encuentra en WPF.
Navegación a direcciones URL
WPF es una tecnología diseñada para entornos de escritorio y puede aceptar parámetros de línea de comandos para dirigir el comportamiento de inicio. Xamarin.Forms puede usar la vinculación de dirección URL profunda para saltar a una página en el inicio.