0

I have a DataGrid which display few roster info of the Employees. I have added a template column with a CheckBox. I want to get the KeyIDs (which is binded from DB) from all the rows of selected (CheckBox selected) Rows. These KeyIDs I have to pass to SQL to Delete the selected Rows (BtnDeleteSelected_Click). Please help.

Here is my DataGrid:

<DataGrid AutoGenerateColumns="False" Grid.Row="1" Height="555" HorizontalAlignment="Left" Margin="0,5,0,0" Name="dgRosterList" VerticalAlignment="Top" Width="980"   ItemsSource="{Binding}" SelectionMode="Single" SelectionUnit="FullRow" CanUserResizeColumns="True" CanUserSortColumns="True"  AlternatingRowBackground="Gainsboro"  AlternationCount="2" IsEnabled="True" Grid.ColumnSpan="2">                
    <DataGrid.Columns>
        <DataGridTemplateColumn Width="30">
            <DataGridTemplateColumn.HeaderTemplate>
                <DataTemplate>
                    <CheckBox x:Name="all" Content="" Click="CheckBox_Click"/>
                </DataTemplate>
            </DataGridTemplateColumn.HeaderTemplate>

            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox Checked="chkSelect_Checked" Name="chkSelect"></CheckBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="Sl No" Binding="{Binding SlNo}"/>
        <DataGridTextColumn Header="Key ID" Binding="{Binding KeyID}" Width="80" Visibility="Hidden"/>
        <DataGridTextColumn Header="Emp ID" Binding="{Binding Emp_ID}" Width="80"/>
        <DataGridTextColumn Header="Emp Name" Binding="{Binding Emp_Name}" Width="200"/>
        <DataGridTextColumn Header="Date" Binding="{Binding PDate, StringFormat={}{0:dd/MM/yyyy}}" Width="100"/>
        <DataGridTextColumn Header="Shift" Binding="{Binding Shift_Code}" Width="80"/>
        <DataGridTextColumn Header="In Time" Binding="{Binding InTime, StringFormat={}{0:hh:mm}}" Width="80"/>
        <DataGridTextColumn Header="Out Time" Binding="{Binding OutTime, StringFormat={}{0:hh:mm}}" Width="80"/>
        <DataGridTemplateColumn Header="Half Day" Width="80">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Image Name="IsHalfDay" Width="15" Height="15" Source="" />
                        <DataTemplate.Triggers>
                            <DataTrigger Binding="{Binding HalfDay}" Value="Yes">
                                <Setter TargetName="IsHalfDay" Property="Source" Value="../Images/ico_tick.gif"/>
                            </DataTrigger>
                        </DataTemplate.Triggers>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Off Day" Width="80">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Image Name="IsOffDay" Width="15" Height="15" Source="" />
                    <DataTemplate.Triggers>
                        <DataTrigger Binding="{Binding OffDay}" Value="Yes">
                            <Setter TargetName="IsOffDay" Property="Source" Value="../Images/ico_tick.gif"/>
                        </DataTrigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Delete" Width="75">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Name="btnDelete" Click="btnDelete_Click" Width="50" Height="20" ToolTip="Delete Roster" CommandParameter="{Binding Path=KeyID}" >
                        <Image Source="../Images/delete.png" Width="15" Height="19"/>
                    </Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="Processed" Binding="{Binding Processed}"  Visibility="Hidden"/>
    </DataGrid.Columns>
    <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <!--<Image Source="{Binding XPath=media:thumbnail/@url}"
                    Width="60" Height="60"/>-->
                <TextBlock Text="{Binding Path=WeeklyOffs}"/>
            </StackPanel>
        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
</DataGrid>
Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68

3 Answers3

2

On the Event:

private void chkSelect_Checked(object sender, RoutedEventArgs e)
{
    dgRosterList.IsSynchronizedWithCurrentItem = true;
}

This will result in highlightingthe current row as though its being selected.

In the XAML use the SelectedItem property of the DataGrid:

SelectedItem="{Binding SelectedEmployeeData}"

In the ViewModel, define the property for SelectedEmployeeData:

private DeleteViewModel m_SelectedEmployeeData;

public DeleteViewModel SelectedEmployeeData
{
    get 
    { 
        return m_SelectedEmployeeData; 
    }

    set 
    { 
        m_SelectedEmployeeData = value;

        if (null != m_SelectedEmployeeData)
        {
            listToSend.Add(m_SelectedEmployeeData.KeyID);
        }
        else
        {
            listToSend.Remove(m_SelectedEmployeeData.KeyID);
        }

        OnPropertyChanged("SelectedEmployeeData");
    }
}

and:

List<int> listToSend = new List<int>();

Where lstSend will contain the KeyIDs which are to be sent to DB.

Here DeleteViewModel is the VM where I'm assuming all the properties pertaining to the columns i.e. KeyID, Emp_ID etc. will be defined.

Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
Arushi Agrawal
  • 619
  • 3
  • 10
0

You can use FindChild() for the access to CheckBox:

    public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
    {
        if (parent == null)
        {
            return null;
        }

        T foundChild = null;

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);

        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);
            T childType = child as T;

            if (childType == null)
            {
                foundChild = FindChild<T>(child, childName);

                if (foundChild != null) break;
            }
            else
                if (!string.IsNullOrEmpty(childName))
                {
                    var frameworkElement = child as FrameworkElement;

                    if (frameworkElement != null && frameworkElement.Name == childName)
                    {
                        foundChild = (T)child;

                        break;
                    }
                    else
                    {
                        foundChild = FindChild<T>(child, childName);

                        if (foundChild != null)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    foundChild = (T)child;
                    break;
                }
        }

        return foundChild;
    }

If you just call this function, it will return only the first control, but we need a CheckBox for the Selected Row. To access the control of selected row to add event SelectionChanged to DataGrid in which to function, which will give a Selected Row:

<DataGrid Name="MyDataGrid" SelectionChanged="MyDataGrid_SelectionChanged">

private void MyDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    try
    {
        // Get the list of rows
        var row_list = GetDataGridRows(MyDataGrid);

        // Check the all rows
        foreach (DataGridRow single_row in row_list)
        {               
            if (single_row.IsSelected == true)
            {
               CheckBox MyCheckBox = FindChild<CheckBox>(single_row, "MyCheckBox"); // here your CheckBox name

                MessageBox.Show(MyCheckBox.IsChecked.ToString());
            }
        }
    }

    catch 
    {
        throw new Exception("Can't get access to DataGridRow");
    }
}

Listing of GetDataGridRows():

public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
    var itemsSource = grid.ItemsSource as IEnumerable;

    if (null == itemsSource)
    {
        yield return null; 
    }

    foreach (var item in itemsSource)
    {
        var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;

        if (null != row)
        {
            yield return row; 
        }
    }
}

As you can see, this practice is not very useful, so it is not very correct. You can add the property MyChecked with OnPropertyChanged() to his DataContext. Example:

    public class YourClass : INotifyPropertyChanged
    {
        private bool? myChecked = null;

        #region INotifyPropertyChanged values

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        public bool? MyChecked
        {
            get
            {
                return myChecked;
            }

            set
            {
                myChecked = value;
                OnPropertyChanged("myChecked");
            }
        }
    }

And used like this:

<CheckBox x:Name="MyCheckBox" IsChecked="{Binding MyChecked}" />        

At each change of the property, OnPropertyChanged() will be triggered and you can do some operations. That is, try to make their actions not on the side of the XAML, and on the side of your data, because in the first case, it is difficult to work with DataGrid.

Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
0

Define a bool property(Like IsRowSelected)in the class that bounded to each row,bind it to Ischecked property of the CheckBox and then you can remove all the rows that IsRowSelected=True in the ViewModel.

mahboub_mo
  • 2,908
  • 6
  • 32
  • 72