Oder „, wie Sie sicherstellen, dass alle Ihre Bindungen korrekt bleiben?“
(dies irgendwie lang ist, aber Geduld mit mir, ich versuchte, es so kurz zu machen, wie ich kann)Statische Überprüfung der Bindungen
Betrachten sie das folgende Beispiel:
<TextBox Name="tb" />
<TextBlock Text="{Binding Text.TheProp, ElementName=tb}" />
es ist perfekt zum Zeitpunkt der Kompilierung bekannt, dass die Bindung nicht korrekt ist (dh der Parser die Art des Elements kennt tb
, und deshalb weiß es die Art der esistEigenschaft, und daher weiß es, dass TheProp
nicht existiert).
Noch wird dieser Code kompilieren und ausführen (obwohl mit einer verbindlichen Fehlermeldung in der Debug-Ausgabe).
Dieses Verhalten kann in einigen Situationen sehr nützlich sein: Egal, welcher genaue Typ meine Daten sind, solange es geeignete Eigenschaften hat, bin ich in Ordnung. So erhalten wir eine Art "deklaratives Entenschreiben".
Aber, Ente tippen ist nicht immer eine gute Sache.
Während ich das MVVM-Muster verwende, kenne ich (meistens) die genauen Typen aller meiner ViewModel-Objekte. Auf der anderen Seite werden die Modelle im Laufe der Zeit immer komplexer, was mich über zukünftige Umgestaltungen beunruhigt: Was passiert, wenn ich beschließe, einige Eigenschaften umzubenennen oder, Gott bewahre, sie in ein separates aggregiertes Objekt zu legen? Was wird mit all meinen Bindungen dann passieren? Muss ich alle XAML-Dateien von Hand rechen lassen? Und auch ohne Refactoring - was ist, wenn ich einfach einen Tippfehler mache?
Ein ähnliches Problem ist bereits an anderen Stellen von XAML gelöst. Wenn Sie beispielsweise einen falschen Eigenschaftsnamen in Style/Setter/@Property
eingeben, erhalten Sie einen Kompilierzeitfehler.
TemplateBinding
bietet auch eine solche Überprüfung. Was sehr praktisch ist.
Also, im Idealfall, ich würde gerne so etwas sehen:
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>
Aber zurück zur Realität. In Wirklichkeit wird alles Träumen in naher Zukunft nicht passieren.
Allerdings bin ich sicher, dass ich nicht die erste Person bin, die dieses Problem hat.
Also, schließlich ist die Frage: Wie stellen Sie sicher, dass Ihre Bindungen korrekt sind? Und dass sie so bleiben?
UWP bietet nun statische Bindung über die ['{x: Bind}' Markup-Erweiterung] (https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/x-bind-markup- Erweiterung). Mysteriöse Wege :) – Funk