> For the complete documentation index, see [llms.txt](https://docs.flatredball.com/gum/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flatredball.com/gum/code/controls/frameworkelement/setbinding.md).

# SetBinding

## Introduction

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:

1. `uiProperty` - the property on the FrameworkElement
2. `vmProperty` - the property on the ViewModel

Usually this method is called using the `nameof` keyword to avoid errors from typos and refactoring.

{% hint style="info" %}
SetBinding exists on both FrameworkElement (Forms objects) as well as GraphicalUiElement (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.
{% endhint %}

## Code Example - Binding a TextBox's Text Property

The following code shows how to bind a TextBox's Text property to a ViewModel's CharacterName property:

```csharp
// Initialize
// Assuming the TextBox's BindingContext is of type PlayerViewModel, and
// also assuming PlayerViewModel has a PlayerName property:
TextBoxInstance.SetBinding(
    nameof(TextBoxInstance.Text),
    nameof(PlayerViewModel.PlayerName));
```

## Binding to a ViewModel Event

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.

```csharp
public class GameViewModel : ViewModel
{
    // Regular ViewModel events can be used in SetBinding
    public event Action EnemySpawned;
    
    // If the event needs to be raised externally (outside of the ViewModel)
    // then a method for raising the event is needed:
    public void RaiseEnemySpawned() => EnemySpawned?.Invoke();
}
```

FrameworkElements can subscribe to this event using the normal event subscribing syntax in C#, but doing so requires access to the ViewModel.

```csharp
var gameViewModel = this.BindingContext as GameViewModel;
if(gameViewModel != null)
{
    gameViewModel.EnemySpawned += HandleEnemySpawned;
}
// later, HandleEnemySpawned is declared:
void HandleEnemySpawned()
{
    // Perform logic related to enemy spawning
}
```

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:

```csharp
void CustomInitialize()
{
    SetBinding(
        nameof(HandleEnemySpawned),
        nameof(GameViewModel.EnemySpawned));
}

void HandleEnemySpawned()
{
    // Perform logic related to enemy spawning
}
```

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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.flatredball.com/gum/code/controls/frameworkelement/setbinding.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
