datagriduwp-xamluno-platformwindows-community-toolkitcommunity-toolkit-mvvm

UnoPlatoform Desktop App DataGrid Template Column with HyperlinkButton Command Binding issue using MVVM


We are developing Desktop application using UnoPlatform in which we are using DataGrid from CommunityToolkit.WinUI.UI.Controls for displaying some data.

So, my requirement is to have HyperlinkButton for one of the DataGrid Column and am using DataTemplate as shown in below code to achieve the functionality.

Issue here is that how to Bind a Command which is there in ViewModel to HyperlinkButton click/Command event?

DataGrid ItemSource is Bind to GridData observable collection from ViewModel.

I am trying to Bind ChildItemInvokedCommand which is there in My StorageAccountViewModel to HyperlinkButton Command however this is not working.

What am i missing here? Any help would be appreciated.

ViewModel :

public partial class StorageAccountViewModel : ObservableObject
{
 public ObservableCollection<ChildFolder> GridData { get; } = new ObservableCollection<ChildFolder>();

private IAsyncRelayCommand _childItemInvokedCommand;
public IAsyncRelayCommand ChildItemInvokedCommand => _childItemInvokedCommand ?? (_childItemInvokedCommand = new AsyncRelayCommand<ChildFolder>(OnChildItemInvoked));

   private async Task OnChildItemInvoked(ChildFolder item)
    {
            // get clicked item here for further functionality

    }
}

ChildFolder.cs

public class ChildFolder
    {
        [JsonProperty("folderName")]
        public string FolderName { get; set; }

        [JsonProperty("folderPath")]
        public string FolderPath { get; set; }        
    }

Page.xamal:

<Page
    x:Class="MDTSStorageExplorer.Views.StorageAccountsPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MDTSStorageExplorer.Views"
    xmlns:models="using:MDTSStorageExplorer.Models"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:controls="using:CommunityToolkit.WinUI.UI.Controls"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid>
<controls:DataGrid
             x:Uid="DataTable"
             x:Name="detailGrid"
              AutoGenerateColumns="False"
             GridLinesVisibility="None" 
              DataContext="{x:Bind ViewModel}"
              ItemsSource="{x:Bind ViewModel.GridData}" >
            <controls:DataGrid.Columns>
            <controls:DataGridTemplateColumn Header="Name" >
            <controls:DataGridTemplateColumn.CellTemplate>
              <DataTemplate>
                  <HyperlinkButton Content="{Binding FolderName}" IsDoubleTapEnabled="True" CommandParameter="{Binding}" Command="{Binding Path=ChildItemInvokedCommand}" >
                                               
                   </HyperlinkButton>
             </DataTemplate>
         </controls:DataGridTemplateColumn.CellTemplate>
        </controls:DataGridTemplateColumn>
       </controls:DataGrid.Columns>
 </controls:DataGrid>
    </Grid>
</Page>

Solution

  • Problem

    The DataContext for your HyperlinkButton is of type ChildFolder. ChildFolder does not have a property called ChildItemInvokedCommand. Therefore, the binding Command="{Binding Path=ChildItemInvokedCommand}" is invalid.

    Solution

    Instead of using a collection of ChildFolder, you can create a collection of ItemViewModels. You can define the item as follows.

    public class ChildFolderItemViewModel
    {
       public ChildFolder ChildFolder { get; set;}
    
       public StorageAccountViewModel ParentViewModel { get; set; }
    }
    
    // Then update your GridData to use the new type.
    public ObservableCollection<ChildFolderItemViewModel> GridData { get; } = new ObservableCollection<ChildFolderItemViewModel>();
    

    Then, you can update your bindings as follows.

    <HyperlinkButton Content="{Binding ChildFolder.FolderName}"
                     IsDoubleTapEnabled="True"
                     CommandParameter="{Binding ChildFolder}"
                     Command="{Binding ParentViewModel.ChildItemInvokedCommand}" />