Verificação estática de ligações
Ou "como você garante que todas as suas ligações permaneçam corretas?"
(isso é meio demorado, mas tenha paciência comigo, tentei torná-lo o mais curto possível)
Considere o seguinte exemplo:
<TextBox Name="tb" />
<TextBlock Text="{Binding Text.TheProp, ElementName=tb}" />
É perfeitamente sabido em tempo de compilação que a ligação está incorreta (ou seja, o analisador conhece o tipo de elementotb
e, portanto, sabe o tipo deText
propriedade e, portanto, sabe queTheProp
não existe).
No entanto, esse código será compilado e executado (embora com uma mensagem de erro de ligação na saída de depuração).
Esse comportamento pode ser muito útil em algumas situações: não importa qual seja o tipo exato de meus dados, desde que tenham propriedades nomeadas adequadamente, estou bem. Assim, temos uma espécie de "digitação declarativa do pato".
Contudo, digitar patos nem sempre é uma coisa boa.
Especificamente, ao usar o padrão MVVM, conheço (na maioria das vezes) os tipos exatos de todos os meus objetos ViewModel. Por outro lado, os modelos se tornam cada vez mais complexos ao longo do tempo, o que me preocupa com a refatoração futura: e se eu decidir renomear algumas propriedades ou, se Deus permitir, colocá-las em um objeto agregado separado? O que vai acontecer com todas as minhas ligações então? Terei que varrer todos os arquivos XAML manualmente? E mesmo sem refatoração - e se eu simplesmente digitar um erro?
Um problema semelhante já foi resolvido em outros locais do XAML. Se, por exemplo, você colocar um nome de propriedade incorreto emStyle/Setter/@Property
, você recebe um erro de tempo de compilação.TemplateBinding
também fornece essa verificação. O que é muito útil.
Então, idealmente, eu adoraria ver algo assim:
ProductViewModel.cs:
public class ProductViewModel
{
public Name { get; set; }
public Price { get; set; }
}
ProductView.XAML:
<UserControl x:Class="Shopping.View.ProductView"
x:DataContextType="vm:ProductViewModel"
xmlns:vm="clr-namespace:Shopping.ViewModel"
... >
<TextBox Text="{Binding Name}" /> <!-- OK -->
<TextBox Text="{Binding Price}" /> <!-- OK -->
<TextBox Text="{Binding ABC}" /> <!-- Compile time error: there is no property ABC in ProductViewModel -->
</UserControl>
ShoppingCart.XAML:
<UserControl x:Class="Shopping.View.ShoppingCartView"
x:DataContextType="vm:ShoppingCartViewModel"
xmlns:vm="clr-namespace:Shopping.ViewModel"
... >
<ItemsControl ItemsSource="{Binding Products}"
ItemType="vm:ProductViewModel" > <!-- Static check happens here
ShoppingCartViewModel.Products must
implement IEnumerable<ProductViewModel> -->
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:ProductViewModel">
<view:ProductView /> <!-- DataContext is known to be of correct type
because of DataTemplate.DataType property -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UserControl>
Mas vamos voltar à realidade. Na realidade, todo esse sonho simplesmente não acontecerá no futuro próximo.
No entanto, tenho certeza de que não sou a primeira pessoa a ter esse problema.
Então, finalmente, a questão é:Como você garante que suas ligações estejam corretas? E que eles permaneçam assim?