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

3
假设我有一个数据网格如下所示:(运行时)
在删除第4行后:
添加两行到datagrid后:
请注意,在第一张图片中,行编号是正确的。当我从Datagrid中删除一个项目时,删除后该行号不见了,如图2所示。在图3中,您可以看到我添加了两行,但行号11重复两次。
在这里,我使用LoadingRow事件进行编号,如下所示:
private void maindg_LoadingRow_1(object sender, DataGridRowEventArgs e)
{
    e.Row.Header = ((e.Row.GetIndex()) + 1).ToString(); 
}

在观察图像2和图像3中出现的问题后,我意识到我需要手动重新编号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,因为选定的索引被重置为-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".....>

1
如果您再次进行数据绑定,问题应该会得到解决。 - user153923
抱歉,你再说一次 databind 是什么意思? - undefined
这是WPF。在WPF中,我没有GridView控件。它是DataGrid - undefined
你明白我的意思吧?你需要重新加载你的数据。 - user153923
我不能,因为我正在开发类似于CustomControl的东西。 - undefined
显示剩余2条评论
2个回答

2

看起来更精确的方法是处理 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();
    }
}

谢谢,那个完美地运行。根据stackoverflow的规则,我会在23小时后授予奖励。 - undefined
1
我已经使用ShowRowNumbers属性来使用您的代码打开/关闭行号。我已经更新了我的问题,并附上了相关代码。 - undefined
抱歉,我遇到了一个小问题。我希望我的用户在每一行都有一个删除按钮。当点击删除按钮时,应该删除该行。我成功地删除了行,但此时行号没有更新。你能解释一下这是为什么吗? - undefined
@Vishal 我猜使用 "OnItemsChanged" 应该可以涵盖所有情况(上面也已经编辑过)。 - undefined
在第一次尝试中,经过您编辑的解决方案似乎起作用了,但是我遇到了一些问题。当我使用我提供的删除按钮进行删除时,它会删除行并刷新行号。但是,它不允许我通过选择行并按下删除键来删除行。因此,除了编辑的代码之外,我尝试重写OnExecutedDelete方法。现在它正常工作了。我已经更新了相关代码的问题描述。 - undefined
你实际上会如何使用这个 - 我需要在XAML中添加什么吗? - undefined

1

事件名称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;
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接