Или " как сделать так, чтобы все ваши привязки оставались правильными? "
(это довольно долго, но потерпите меня, я пытался сделать его настолько коротким, насколько смог)
Рассмотрим следующий пример:
<TextBox Name="tb" />
<TextBlock Text="{Binding Text.TheProp, ElementName=tb}" />
Во время компиляции совершенно точно известно, что привязка неверна (т. Е. Синтаксический анализатор знает тип элемента tb
, иследовательно, он знает тип своего свойства Text
и, следовательно, знает, что TheProp
не существует).
Тем не менее, этот код будет компилироваться и выполняться (хотя с сообщением об ошибке привязки в выводе отладки).
Это поведение может оказаться очень полезным в некоторых ситуациях: независимо от того, какого типа мои данные, если они имеют соответствующие имена, у меня все в порядке.Таким образом, мы получаем своего рода «декларативную типизацию утки».
Однако , типизация утки - не всегда хорошая вещь.
В частности, при использовании шаблона MVVM я знаю (большинствовремени) точные типы всех моих объектов ViewModel.С другой стороны, модели со временем становятся все более и более сложными, что заставляет меня беспокоиться о будущем рефакторинге: что, если я решу переименовать некоторые свойства или, не дай Бог, поместить их в отдельный агрегированный объект?Что будет потом со всеми моими привязками?Придется ли мне вручную разгребать все файлы XAML?И даже без рефакторинга - что если я просто сделаю опечатку?
Подобная проблема уже решена в других местах XAML.Например, если вы указали неверное имя свойства в Style/Setter/@Property
, вы получите ошибку времени компиляции.
TemplateBinding
также обеспечивает такую проверку.Что очень удобно.
Так что в идеале я хотел бы увидеть что-то вроде этого:
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>
Но вернемся к реальности.На самом деле все эти сновидения просто не произойдут в ближайшем будущем.
Однако я уверен, что я не первый, у кого возникла эта проблема.
Итак, наконец, вопрос в том,: Как убедиться, что ваши привязки верны?И что они остаются такими?