从datagrid中删除项目后重置行号

时间:2014-07-08 21:15:53

标签: c# wpf datagrid

假设我有一个dataGrid,如下所示:( at-runtime)

enter image description here

删除第4行后:

enter image description here

向datagrid添加两行后:

enter image description here

请注意,在第一张图片中,行编号很好。当我从Datagrid中删除一个项目时,删除后该行号丢失,如图2所示。在图像3中,您可以看到我已经有两个新行,但行号11重复了两次。

这里我使用LoadingRow事件进行编号,如下所示:

private void maindg_LoadingRow_1(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = ((e.Row.GetIndex()) + 1).ToString(); 
}

在得到image2和image3中显示的问题后,我明白我应该手动重新编号dataGridRowHeaders。所以,我在DaaGrid的PreviewKeyDown事件中尝试了以下代码:

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();
        }
    }
}

当我再次运行程序时,我看不到输出的任何变化。所以我认为DataGrid在删除行之前重新编号,所以我将该代码移动到了PreviewKeyUp。我得到了IndexOutOfRangeException,因为Selected索引重置为-1。

如何才能获得正确的编号?

ShowRowNumbers属性的解决方案,以便开发人员可以打开/关闭行号:

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();
    }
}

在XAML中:

<DataGrid ......
          ShowRowNumbers="True".....>

2 个答案:

答案 0 :(得分:1)

似乎更精确的方法是处理 OnExecutedDelete OnItemsChanged,而不是尝试与删除按键同步。也许你可以继承DataGrid并以这种方式刷新行:

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();
    }
}

答案 1 :(得分:0)

事件名称RowsRemoved。然后写下面的代码

 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;
        }
    }