Compartilhar via


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:

  1. ContentPage
  2. ContentView
  3. ContentPresenter
  4. 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 strings, s etc., intbem 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 XamlReadero . 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:

  1. {x:Array}
  2. {Binding}
  3. {DynamicResource}
  4. {x:Null}
  5. {x:Static}
  6. {StaticResource}
  7. {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:

  1. O objeto deve derivar de BindableObject.
  2. Deve haver um campo estático público do tipo BindableProperty declarado para definir a chave de armazenamento de suporte para a propriedade.
  3. Deve haver um wrapper de propriedade de instância pública que use GetValue e SetValue 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 DataTemplates 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 ResourceDictionaryarquivo .

Além disso, eles não são tão flexíveis quanto sua contraparte do WPF.

  1. O elemento raiz do DataTemplate deve ser sempre um ViewCell objeto.
  2. 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.
  3. DataTemplateSelectortambém tem suporte, mas deriva ItemTemplate de DataTemplate 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, UserControls 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.

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.