SetBinding establishes a relationship between a property on the binding context and a property on the calling FrameworkElement. SetBinding is used to keep two properties synced, usually resulting changes on one of the properties automatically updating the other property.
SetBinding requires the bound FrameworkElement having a valid BindingContext - which can be either directly set or indirectly inherited from its parent.
The following are common SetBinding Examples:
Binding a TextBox's Text property to a ViewModel's CharacterName property
Binding a Button's IsEnabled property to a ViewModel's HasEnoughMoney property
Binding a ListBox's Items property to a ViewModel's AvailableFastTravelDestinations property
Binding a custom made PlayerJoinItem to a ViewModel's JoinState property
SetBinding takes two parameters:
uiProperty
- the property on the FrameworkElement
vmProperty
- the property on the ViewModel
Usually this method is called using the nameof
keyword to avoid errors from typos and refactoring.
SetBinding exists on both FrameworkElement (Forms objects) as well as BindableGue (Gum runtime objects). This document is written in context of Forms controls, but binding can be performed directly on a runtime object's properties, including a FrameworkElement's Visual instance.
The following code shows how to bind a TextBox's Text property to a ViewModel's CharacterName property:
Binding can be performed on ViewModel events. When a bound event is raised, the FrameworkElement's bound handler is raised. Binding to an event is similar to explicitly adding an event handler, but the SetBinding method enables binding to events without having a ViewModel instance.
For example, consider a ViewModel which contains an event called EnemySpawned, which would be an event raised whenever a new enemy is spawned in a game.
FrameworkElements can subscribe to this event using the normal event subscribing syntax in C#, but doing so requires access to the ViewModel.
The code above is not as straight-forward as it might seem. BindingContext must be a valid GameViewModel
, which means the code should be written in a place where the BindingContext is guaranteed to be set, such as overwriting the FrameworkElement's HandleVisualBindingContextChanged
method. Furthermore, to prevent memory leaks a FrameworkElement should properly unsubscribe from its ViewModel events whenever its ViewModel changes.
We can simplify this code by letting the FrameworkElement handle this complexity by using SetBinding. The following code shows how this might look:
The code above uses the same syntax as binding properties, but in this case we are binding an event to a method on our framework element.