Manchmal ist es doch überraschend, an welchen Stellen Bindings verwendet werden können. So handelt es sich bei der Width Eigenschaft einer ColumnDefinition im Grid um eine DependencyProperty, die man dynamisch binden kann. Mit ganz witzigen Effekten, wie ich nun beschreiben möchte – hier eine schnelle Lösung, elegant wird es erst bei Einsatz von ValueConvertern.
In einem privaten Projekt werden zu einer Buslinie die Haltestellen und deren Abstand eingegeben. Ich wollte nun so einen so schönen Zeitstrahl haben, wie man ihn hier in der Gegend auf den ausgegängten Busfahrplänen findet.
Im Programm sind bereits die Haltestelle als Objekte (Knotenpunkt) vorhanden, die INotifyPropertyChanged implementieren. Eine dieser Eigenschaften ist die Fahrzeit zwischen zwei Haltestellen in Minuten. Ich habe nun eine neue Eigenschaft der Art GridLength hinzugefügt – wie gesagt, ein ValueConverter würde eine sauberere Trennung der Softwareschichten bedeuten. Diese Eigenschaft meldet entweder als Breite 0 Pixel (wenn die Fahrzeit 0 ist) oder die (positive) Fahrzeit mit dem GridUnitType.Star – entsprechend der XAML Texteingabe 1*, 2*, 3* etc.
Ein UserControl (FahrplanAnzeigen) wird nun an eine Liste von Haltestellen gebunden – die Liste selbst wird nur sehr faul überwacht und Änderungen führen zu einem vollständigen Neuaufbau: in einem echten Stück Software würde man das sicher optimieren. Für jede Haltestelle wird eine ColumnDefinition erzeugt und die beschrieben Eigenschaft über die BindingOperations an die Width gebunden.
Silverlight sorgt nun mit ein bisschen XAML Definition automatisch dafür, dass die Haltepunkte proportional über den Zeitstrahl verteilt werden. Reaktionen bei Änderung der Größe sind nicht notwendig. Mehr noch: ändert man die Fahrzeit eines Haltepunktes im Formular, so passt sich der Zeitstrahl über das Binding ohne irgendwelche weitere Interaktion des Programms an. Das sieht schon recht witzig aus – vor allem für ein geschenktes Feature.
Happy Coding
Jochen