Skip to content

Commit

Permalink
chore: Resolving csm binding docs comments
Browse files Browse the repository at this point in the history
  • Loading branch information
eriklimakc committed May 29, 2024
1 parent 1c43194 commit 6d8d111
Showing 1 changed file with 46 additions and 51 deletions.
97 changes: 46 additions & 51 deletions doc/Learn/Markup/Binding-To-DataTemplates.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,76 +4,71 @@ uid: Uno.Extensions.Markup.BindToDataTemplate

# Binding to DataTemplates

When working with `DataTemplate`s, accessing data or commands from the parent context can be challenging. `DataTemplate`s operate within their own scope, making it difficult to bind properties or trigger actions in the parent `DataContext`. This separation can lead to confusion, especially when dealing with nested templates and multiple levels of data context.
When working with `DataTemplate`s, accessing data or commands from the parent context can be challenging. `DataTemplate`s operate within their own scope, making it difficult to bind properties or trigger actions from the parent `DataContext`. This separation can lead to confusion, especially when dealing with nested templates and multiple layers of data context.

In the following example, the parent `DataContext` is the `ViewModel`. The `ViewModel` contains an `ICommand RemoveItemCommand`. The code demonstrates how to access that `ICommand` inside the `ItemTemplate` of the `ListView`.
In the following example, the parent `DataContext` is the `ViewModel` that contains a `RemoveItemCommand`. The code demonstrates how to access that `ICommand` within the `ListView`'s `ItemTemplate`.

```csharp
this.DataContext(new ViewModel(), (page, vm)
=> page
.Content(
new ListView()
.ItemsSource(() => vm.Items)
.ItemTemplate<Item>(item =>
new StackPanel()
.Children(
new TextBlock()
.Text(() => item.Text),
new Button()
.Content("Delete")
.CommandParameter(() => item)

// Since we have access to the `page` and `vm` alias from the DataContext method
// We can take advantage of them and use them on our binding expression
.Command(x => x.Source(page)
.DataContext()
.Binding(() => vm.RemoveItemCommand)
)
)
)
)
)
this.DataContext(new ViewModel(), (page, vm) => page.Content(
new ListView()
.ItemsSource(() => vm.Items)
.ItemTemplate<Item>(item =>
new StackPanel()
.Children(
new TextBlock().Text(() => item.Text),
new Button()
.Content("Delete")
.CommandParameter(() => item)
// Since we have access to the `page` and `vm` alias from the DataContext method
// We can take advantage of them and use them on our binding expression
.Command(x => x
.Source(page)
.DataContext()
.Binding(() => vm.RemoveItemCommand)
)
)
)
))
```

Alternatively, we could extract the `Button` to a helper method and take advantage of the `RelativeSource` method to provide the `CommandParameter`.
Alternatively, we could extract the `Button` into a helper method and take advantage of the `RelativeSource` method to provide the `CommandParameter`.

```csharp
...

.Children(
new TextBlock()
.Text(() => item.Text),
CreateButton()
CreateRemoveButton()
)
...

private Button CreateButton()
=> new Button()
.Content("Delete")
.CommandParameter(x => x.RelativeSource<Button>(RelativeSourceMode.TemplatedParent)
.Binding(btn => btn.DataContext)
)
.Command(x => x
// Since we don't have access to the `page` alias here (as we have in the previous example)
// We need to set `this` as the source
.Source(this)
// Here we specify the DataContext type so that we can access the ViewModel alias in the Binding method
.DataContext<MainViewModel>()
.Binding(vm => vm.RemoveItemCommand)
);
private Button CreateRemoveButton() => new Button()
.Content("Delete")
.CommandParameter(x => x
.RelativeSource<Button>(RelativeSourceMode.TemplatedParent)
.Binding(btn => btn.DataContext)
)
.Command(x => x
// Since we don't have access to the `page` alias here (as we have in the previous example)
// We need to set `this` as the source
.Source(this)
// Here we specify the DataContext type so that we can access the ViewModel alias in the Binding method
.DataContext<MainViewModel>()
.Binding(vm => vm.RemoveItemCommand)
);
```

Since the `CommandParameter` we're providing is the `DataContext` of the `ItemTemplate` from the `ListView`, we can simplify it by using the XAML equivalent of `{Binding .}`. In C# Markup this is `(x => x.Binding())`:
Given that `CommandParameter` is the `DataContext` of the `ListView.ItemTemplate`, we can simplify it by using the XAML equivalent of `{Binding .}`. In C# Markup this is `(x => x.Binding())`:

```csharp
private Button CreateButton()
=> new Button()
.Content("Delete")
.CommandParameter(x => x.Binding())
.Command(x => x.Source(this)
.DataContext<MainViewModel>()
.Binding(vm => vm.RemoveItemCommand)
);
private Button CreateRemoveButton() => new Button()
.Content("Delete")
.Command(x => x.Source(this)
.DataContext<MainViewModel>()
.Binding(vm => vm.RemoveItemCommand)
)
.CommandParameter(x => x.Binding());
```

For more information about `Source` and `RelativeSource` usages in C# Markup, refer to the [Source and Relative Source](xref:Uno.Extensions.Markup.SourceUsage) documentation.
Expand Down

0 comments on commit 6d8d111

Please sign in to comment.