diff --git a/doc/Learn/Markup/Binding-To-DataTemplates.md b/doc/Learn/Markup/Binding-To-DataTemplates.md new file mode 100644 index 0000000000..6d16a00e5b --- /dev/null +++ b/doc/Learn/Markup/Binding-To-DataTemplates.md @@ -0,0 +1,84 @@ +--- +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 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` 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 => + 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` into a helper method and take advantage of the `RelativeSource` method to provide the `CommandParameter`. + +```csharp +... + +.Children( + new TextBlock() + .Text(() => item.Text), + CreateRemoveButton() +) +... + +private Button CreateRemoveButton() => new Button() + .Content("Delete") + .CommandParameter(x => x + .RelativeSource