WPF vs. Xamarin.Forms: semelhanças e diferenças
Modelos de controle
O WPF dá suporte ao conceito de Modelos de Controle que fornecem as instruções de visualização para um controle (Button
, ListBox
, etc.). Conforme mencionado acima, o Xamarin.Forms usa classes de renderização concretas para isso que interagem com a plataforma nativa (iOS, Android etc.) para visualizar o controle.
No entanto, o Xamarin.Forms tem um ControlTemplate
tipo – ele é usado para criar temas de Page
objetos. Ele fornece uma definição para um Page
que fornece conteúdo consistente, mas permite que o usuário da página altere cores, fontes, etc. e até mesmo adicione elementos para torná-la exclusiva para o aplicativo.
Os usos comuns para isso são coisas como caixas de diálogo de autenticação, prompts e para fornecer uma aparência de página padronizada, mas temática, que pode ser personalizada no aplicativo. Como parte desse suporte, muitos controles familiares nomeados pelo WPF são usados:
ContentPage
ContentView
ContentPresenter
TemplateBinding
Mas é importante saber que eles não estão servindo à mesma finalidade no Xamarin.Forms. Para obter mais informações sobre esse recurso, confira a página de documentação.
XAML
O XAML é usado como a linguagem de marcação declarativa para WPF e Xamarin.Forms. Na maioria das vezes, a sintaxe é idêntica - a principal diferença são os objetos definidos/criados pelos gráficos XAML.
O Xamarin.Forms dá suporte à especificação XAML 2009; isso facilita a definição de dados como
string
s, s etc.,int
bem como a definição de tipos genéricos e a passagem de argumentos para construtores.No momento, não há como carregar dinamicamente o XAML como o WPF pode com
XamlReader
o . No entanto, você pode obter a mesma funcionalidade básica com um pacote NuGet.
Extensões de marcação
O Xamarin.Forms dá suporte à extensão do XAML por meio de extensões de marcação, assim como o WPF. Fora da caixa, ele tem os mesmos blocos de construção básicos:
{x:Array}
{Binding}
{DynamicResource}
{x:Null}
{x:Static}
{StaticResource}
{x:Type}
Além disso, ele inclui {x:Reference}
a especificação XAML 2009 e uma {TemplateBinding}
extensão de marcação que é usada para a versão especializada do ControlTemplate
com suporte do Xamarin.Forms.
Aviso
O ControlTemplate
suporte não é o mesmo - embora tenha o mesmo nome.
O Xamarin.Forms também dá suporte a extensões de marcação personalizadas, mas a implementação é um pouco diferente. No WPF, você deve derivar de MarkupExtension
- uma classe base abstrata. No Xamarin.Forms, isso é substituído por uma interface IMarkupExtension
ou IMarkupExtension<T>
que é mais flexível.
Assim como o WPF, o único método necessário é um ProvideValue
método para retornar o valor da extensão de marcação.
Infraestrutura de associação
Um dos principais conceitos transportados é uma infraestrutura de associação de dados para conectar propriedades visuais a propriedades de dados do .NET. Isso permite padrões de arquitetura como MVVM. O design básico é idêntico - você tem uma classe base associável BindableObject, no WPF essa é a classe DependencyObject . Essa classe base é usada como o ancestral raiz para todos os objetos que participarão como destinos na associação de dados. Em seguida, as classes derivadas expõem objetos BindableProperty que atuam como o armazenamento de suporte para valores de propriedade (eles são definidos como objetos DependencyProperty no WPF).
Definindo propriedades vinculáveis
A definição de uma propriedade associável no Xamarin.Forms é a mesma do WPF:
- O objeto deve derivar de
BindableObject
. - Deve haver um campo estático público do tipo
BindableProperty
declarado para definir a chave de armazenamento de suporte para a propriedade. - Deve haver um wrapper de propriedade de instância pública que use
GetValue
eSetValue
para recuperar e alterar o valor das propriedades.
Para obter um exemplo completo, consulte Propriedades associáveis no Xamarin.Forms.
Propriedades anexadas
As propriedades anexadas são um subconjunto da propriedade associável e funcionam da mesma maneira que no WPF. A principal diferença é que o wrapper de propriedade é omitido nesse caso e substituído por um conjunto de métodos get/set estáticos na classe proprietária. Consulte Propriedades anexadas no Xamarin.Forms para obter mais informações.
Usando o mecanismo de associação
O processo para usar o mecanismo de associação é o mesmo que no WPF. Ele pode ser utilizado no code-behind criando um Binding
objeto vinculado a um objeto de origem (qualquer tipo .NET) e um valor de propriedade opcional (se omitido, ele trata o objeto de origem como a própria propriedade, assim como o WPF). Em seguida, você pode usar SetBinding
em qualquer um BindableObject
para associar a associação a um BindableProperty
.
Como alternativa, você pode definir a relação de associação em XAML usando o BindingExtension
. Ele tem os mesmos valores básicos que a extensão no WPF.
O suporte de associação e o mecanismo são mais semelhantes à implementação do Silverlight do que ao WPF. Há vários recursos ausentes que não foram implementados no Xamarin.Forms:
- Não há suporte para os seguintes recursos em associações:
- BindingGroupName
- BindsDirectlyToSource
- IsAsync
- MultiBinding
- NotifyOnSourceUpdated
- NotifyOnTargetUpdated
- NotifyOnValidationError
- UpdateFonteTrigger
- UpdateSourceExceptionFilter
- ValidatesOnDataErrors
- ValidatesOnExceptions
- Coleção ValidationRules
- XPath
- XmlNamespaceManager
Fonte Relativa
Não há suporte para RelativeSource
associações. No WPF, eles permitem que você associe a outros elementos visuais definidos em XAML. No Xamarin.Forms, essa mesma funcionalidade pode ser obtida usando a extensão de {x:Reference}
marcação. Por exemplo, supondo que tenhamos um controle com o nome "otherControl" que tenha uma propriedade Text, podemos associá-lo assim:
WPF
Text={Binding RelativeSource={RelativeSource otherControl}, Path=Text}
Xamarin.Forms
Text={Binding Source={x:Reference otherControl}, Path=Text}
O mesmo recurso pode ser usado para o {RelativeSource Self}
recurso. No entanto, não há suporte para localizar ancestrais por tipo ({RelativeSource FindAncestor}
).
Contexto de associação
No WPF, você pode definir um valor de DataContext
propriedade que representa a origem de associação padrão. Se a origem de uma associação não for definida, esse valor de propriedade será usado. O valor é herdado na árvore visual, permitindo que ele seja definido em um nível mais alto e, em seguida, usado por filhos.
No Xamarin.Forms, esse mesmo recurso está disponível, mas o nome da propriedade é BindingContext
.
Conversores de valor
Os conversores de valor têm suporte total no Xamarin.Forms, assim como no WPF. A mesma forma de interface é usada, mas o Xamarin.Forms
Xamarin.Forms tem a interface definida no namespace.
Model-View-ViewModel
O MVVM é totalmente compatível com o WPF e o Xamarin.Forms.
O WPF inclui um built-in RoutedCommand
que às vezes é usado; O Xamarin.Forms não tem suporte interno a comandos além da definição da ICommand
interface. Você pode incluir uma variedade de estruturas MVVM para adicionar as classes base necessárias para implementar o MVVM.
INotifyPropertyChanged e INotifyCollectionChanged
Ambas as interfaces têm suporte total em associações do Xamarin.Forms. Ao contrário de muitas estruturas baseadas em XAML, as notificações de alteração de propriedade podem ser geradas em threads em segundo plano no Xamarin.Forms (assim como no WPF) e o mecanismo de associação fará a transição corretamente para o thread da interface do usuário.
Além disso, ambos os ambientes dão suporte SynchronizationContext
e async
/await
para fazer o marshaling de thread adequado. O WPF inclui a classe em todos os elementos visuais, o Dispatcher
Xamarin.Forms tem um método Device.BeginInvokeOnMainThread
estático que também pode ser usado (embora SynchronizationContext
seja preferível para codificação multiplataforma).
- O Xamarin.Forms inclui um que dá suporte a notificações de
ObservableCollection<T>
alteração de coleção. - Você pode usar
BindingBase.EnableCollectionSynchronization
para habilitar atualizações entre threads para uma coleção. A API é um pouco diferente da variação do WPF, verifique os documentos para obter detalhes de uso.
Modelos de dados
Há suporte para modelos de dados no Xamarin.Forms para personalizar a renderização de uma ListView
linha (célula). Ao contrário do WPF, que pode utilizar DataTemplate
s para qualquer controle orientado a conteúdo, o Xamarin.Forms atualmente os usa apenas para ListView
. A definição de modelo pode ser definida embutida (atribuída à ItemTemplate
propriedade) ou como um recurso em um ResourceDictionary
arquivo .
Além disso, eles não são tão flexíveis quanto sua contraparte do WPF.
- O elemento raiz do
DataTemplate
deve ser sempre umViewCell
objeto. - Os Gatilhos de Dados têm suporte total em um Modelo de Dados, mas devem incluir uma
DataType
propriedade que indique o tipo da propriedade à qual o gatilho está associado. DataTemplateSelector
também tem suporte, mas derivaItemTemplate
deDataTemplate
e, portanto, é apenas atribuído diretamente à propriedade (vs.ItemTemplateSelector
no WPF).
ItemsControl
Não há equivalente interno a um ItemsControl
no Xamarin.Forms; mas há um personalizado para o Xamarin.Forms disponível aqui.
Controles do usuário
No WPF, UserControl
s são usados para fornecer uma seção da interface do usuário que tem comportamento associado. No Xamarin.Forms, usamos o para ContentView
a mesma finalidade. Ambos dão suporte à associação e inclusão em XAML.
Navegação
O WPF inclui um raramente usado NavigationService
que pode ser usado para fornecer um recurso de navegação "semelhante ao navegador". A maioria dos aplicativos não se preocupou com isso e, em vez disso, usou elementos diferentes Window
ou seções diferentes da janela para exibir dados.
Em dispositivos de telefone, telas diferentes geralmente são a solução e, portanto, o Xamarin.Forms inclui suporte para várias formas de navegação:
Estilo de navegação | Tipo de Página |
---|---|
Baseado em pilha (push/pop) | NavigationPage |
Mestre/Detalhes | MasterDetailPage |
Tabulações | TabbedPage |
Deslize para a esquerda/direita | CarouselView |
A NavigationPage
abordagem é a mais comum, e cada página tem uma Navigation
propriedade que pode ser usada para enviar ou remover páginas da pilha de navegação. Este é o equivalente mais próximo do NavigationService
encontrado no WPF.
Navegação por URL
O WPF é uma tecnologia orientada para desktop e pode aceitar parâmetros de linha de comando para direcionar o comportamento de inicialização. O Xamarin.Forms pode usar a vinculação de URL profunda para ir para uma página na inicialização.