Reputation: 6378
Suppose I have a dataGrid as shown below: (at-runtime)
After deleting row no.4:
After adding two more rows to the datagrid:
Notice that in the first picture the row numbering is good. When I delete an item from the Datagrid, that row number is missing after deletion as shown in image 2. In image 3 you can see that I have aded two new rows but the row number 11 is repeated twice.
Here I have got numbering using LoadingRow event as follows :
private void maindg_LoadingRow_1(object sender, DataGridRowEventArgs e)
{
e.Row.Header = ((e.Row.GetIndex()) + 1).ToString();
}
After getting the problems as shown in image2 and image3 I understood that I should manually renumber the dataGridRowHeaders. So, I tried the below code in PreviewKeyDown event of the DaaGrid :
if (e.Key == Key.Delete)
{
DataGridRow dgr = (DataGridRow)(maindg.ItemContainerGenerator.ContainerFromIndex(maindg.SelectedIndex));
if (!(dgr.IsEditing))
{
foreach (var item in maindg.Items)
{
dgr.Header = ((dgr.GetIndex()) + 1).ToString();
}
}
}
When I run the program again I could not see any changes in the output. So I thought that the DataGrid is renumbered just before deletion of the row, so I moved that code to PreviewKeyUp. There I got IndexOutOfRangeException as Selected index is reset to -1.
What can I do to get the correct numbering?
Solution with ShowRowNumbers Property so that developers can turn on/off the Row Numbers :
public class ExtendedDataGrid : DataGrid
{
public static bool GetShowRowNumbers(DependencyObject obj)
{
return (bool)obj.GetValue(ShowRowNumbersProperty);
}
public static void SetShowRowNumbers(DependencyObject obj, bool value)
{
obj.SetValue(ShowRowNumbersProperty, value);
}
public static readonly DependencyProperty ShowRowNumbersProperty =
DependencyProperty.RegisterAttached("ShowRowNumbers", typeof(bool), typeof(ExtendedDataGrid), new UIPropertyMetadata(false));
public ExtendedDataGrid()
{
LoadingRow += (sender, args) =>
{
if (GetShowRowNumbers(this))
RefreshRowNumber(args.Row);
};
}
protected override void OnExecutedDelete(ExecutedRoutedEventArgs e)
{
base.OnExecutedDelete(e);
if (GetShowRowNumbers(this))
RefreshRowNumbers();
}
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
if (GetShowRowNumbers(this))
RefreshRowNumbers();
}
private void RefreshRowNumbers()
{
for (int i = 0; i < Items.Count; i++)
RefreshRowNumber((DataGridRow)ItemContainerGenerator.ContainerFromIndex(i));
}
private void RefreshRowNumber(DataGridRow row)
{
if(row != null)
row.Header = ((row.GetIndex()) + 1).ToString();
}
}
In XAML:
<DataGrid ......
ShowRowNumbers="True".....>
Upvotes: 3
Views: 3792
Reputation: 9
event name RowsRemoved. Then write below code
private void dataGridView1_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
int cct = dataGridView1.Rows.Count; //count how many rows in dgv
int cnt = 0;
int replace_no = 1;
while(cnt < cct)
{
dataGridView1.Rows[cnt].Cells[0].Value = replace_no.ToString(); //replace S No
cnt = cnt + 1;
replace_no = replace_no + 1;
}
}
Upvotes: 1
Reputation: 102793
It seems like a more precise approach would be to handle OnExecutedDelete
OnItemsChanged
rather than trying to sync up with the delete key-press. Maybe you could subclass DataGrid
and refresh the rows this way:
public class ExtendedDataGrid : DataGrid
{
public ExtendedDataGrid()
{
LoadingRow += (sender, args) => RefreshRowNumber(args.Row);
}
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
RefreshRowNumbers();
}
private void RefreshRowNumbers()
{
for (int i = 0; i < Items.Count; i++)
RefreshRowNumber((DataGridRow)ItemContainerGenerator.ContainerFromIndex(i));
}
private void RefreshRowNumber(DataGridRow row)
{
if (row != null)
row.Header = ((row.GetIndex()) + 1).ToString();
}
}
Upvotes: 2