[UWP][C#] Datagrid with button column - detect which row is selected

Paula Morgan 276 Reputation points
2020-06-24T18:10:26.233+00:00

Hi,

I have a datagrid with a button in the first column. When I click the button I want to know which row it is in.

How do I do that?

Thanks,
Paula

Universal Windows Platform (UWP)
0 comments No comments
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,306 Reputation points
    2020-06-24T18:51:25.21+00:00

    Hi, you can include DataGridTemplateColumn with Button. Command is bound to ICommand property of ViewModel and CommandParameter is bound to data item of row. Clicking button the event method gets the reference to data object of clicked row.

    <Page  
        x:Class="App1.Page05"  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        xmlns:local="using:App05"  
        xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"  
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
        mc:Ignorable="d"  
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">  
      <Page.Resources>  
        <local:ViewModel x:Key="vm"/>  
      </Page.Resources>  
      <Grid DataContext="{StaticResource vm}">  
        <Grid.RowDefinitions>  
          <RowDefinition/>  
          <RowDefinition Height="Auto"/>  
        </Grid.RowDefinitions>  
        <controls:DataGrid Grid.Row="0" ItemsSource="{Binding View}" Height="200">  
          <controls:DataGrid.Columns>  
            <controls:DataGridTemplateColumn>  
              <controls:DataGridTemplateColumn.CellTemplate>  
                <DataTemplate>  
                  <StackPanel>  
                    <Button Content="Select" Command="{Binding Cmd, Source={StaticResource vm}}" CommandParameter="{Binding}"/>  
                  </StackPanel>  
                </DataTemplate>  
              </controls:DataGridTemplateColumn.CellTemplate>  
            </controls:DataGridTemplateColumn>  
          </controls:DataGrid.Columns>  
        </controls:DataGrid>  
        <TextBlock Grid.Row="1" Text="{Binding Log}"/>  
      </Grid>  
    </Page>  
    

    --------------------------------------------------------------

    using System;  
    using System.Collections.ObjectModel;  
    using System.ComponentModel;  
    using System.Runtime.CompilerServices;  
    using System.Windows.Input;  
    using Windows.UI.Xaml.Controls;  
    using Windows.UI.Xaml.Data;  
      
    namespace App05  
    {  
      public class ViewModel : INotifyPropertyChanged  
      {  
        private ObservableCollection<Data> col;  
        public ObservableCollection<Data> View  
        {  
          get  
          {  
            if (col == null) LoadData();  
            return col;  
          }  
        }  
      
        public string Log { get; set; }  
      
        public ICommand Cmd { get => new RelayCommand(CmdExec); }  
        private void CmdExec(Object obj)  
        {  
          var d = obj as Data; // get data object from CommandParameter  
          if (d == null) return; // exit if there's no data  
          Log = $"Row ID: {d.ID}, Info: {d.Info}"; // write info  
          OnPropertyChanged(nameof(Log)); // refresh UI   
        }  
      
        private void LoadData()  
        {  
          col = new ObservableCollection<Data>();  
          for (int i = 1; i < 100; i++) col.Add(new Data() { ID = i, Info = $"Row {i}" });  
        }  
      
        #region PropertyChanged  
        public event PropertyChangedEventHandler PropertyChanged;  
        internal void OnPropertyChanged([CallerMemberName] string propName = "") =>  
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));  
        #endregion  
      }  
      
      public class Data  
      {  
        public int ID { get; set; }  
        public string Info { get; set; }  
      }  
      
      public class RelayCommand : ICommand  
      {  
        private readonly Predicate<object> _canExecute;  
        private readonly Action<object> _execute;  
        public event EventHandler CanExecuteChanged;  
        public RelayCommand(Action<object> execute) : this(execute, null) { }  
        public RelayCommand(Action<object> execute, Predicate<object> canExecute) { _execute = execute; _canExecute = canExecute; }  
        public bool CanExecute(object parameter) => (_canExecute == null) ? true : _canExecute(parameter);  
        public void Execute(object parameter) => _execute(parameter);  
        public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);  
      }  
    }  
    

    10520-24-06-2020-21-07-17.gif

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful