I'm trying to bind a IAsyncRelayCommand
(MVVM Toolkit) from my view model using x:Bind
within a DataTemplate.
This is my view model:
public class BuildingViewModel : ObservableObject
{
public ObservableCollection<ObservableProjectItem> ProjectItems { get; } = new ObservableCollection<ObservableProjectItem>();
public IAsyncRelayCommand AddProjectItemCommand { get; }
public BuildingViewModel()
{
AddProjectItemCommand = new AsyncRelayCommand<ContentDialog>(async (dialog) => await AddProjectItem(dialog));
}
private async Task AddProjectItem(ContentDialog dialog)
{
// Do something
}
}
And this my view (XAML):
<TreeView ItemsSource="{x:Bind ViewModel.ProjectItems}">
<TreeView.ItemTemplate>
<DataTemplate x:DataType="model:ObservableProjectItem">
<TreeViewItem ItemsSource="{x:Bind Children}">
<TextBlock Text="{x:Bind Name}" />
<TreeViewItem.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Command="{HERE I WANT BIND THE COMMAND}" />
<MenuFlyoutItem Text="Löschen" Icon="Delete" />
</MenuFlyout>
</TreeViewItem.ContextFlyout>
</TreeViewItem>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
The view have the following code behind:
public sealed partial class BuildingView : Page
{
public BuildingView()
{
this.InitializeComponent();
}
internal BuildingViewModel ViewModel = Ioc.Default.GetService<BuildingViewModel>();
}
My problem is {x:Bind ViewModel.AddProjectItemCommand}
doesn't work. Within the DataTemplate the x:Bind
scope is ObservableProjectItem
. How can I navigate to my root ViewModel respectively bind my command declared in the view model?
Unfortunately, these kind of operations are not well supported by x:Bind (see this WinUI issue for more context). You could however use Binding
to solve that problem. For this, you need to set x:Name on your page and use the ElementName
property:
<Page x:Name="MyPage">
<TreeView ItemsSource="{x:Bind ViewModel.ProjectItems}">
<TreeView.ItemTemplate>
<DataTemplate x:DataType="model:ObservableProjectItem">
<TreeViewItem ItemsSource="{x:Bind Children}">
<TextBlock Text="{x:Bind Name}" />
<TreeViewItem.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Command="{Binding Path=AddProjectItemCommand, ElementName=MyPage}" />
<MenuFlyoutItem Text="Löschen" Icon="Delete" />
</MenuFlyout>
</TreeViewItem.ContextFlyout>
</TreeViewItem>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Page>