在 DataGridView 垂直滚动条上绘制标记

Gil*_*h22 3 .net c# datagridview scrollbar winforms

我正在开发一个项目,其中 DataGridView 中的单元格会突出显示。我想知道是否可以在滚动条本身上做标记来指示这些突出显示的位置。任何想法可能会有帮助。

TaW*_*TaW 5

是、否和也许

是的:根据这个,这是可能的。然而,这只是一个链接答案;不确定那会导致哪里..

否:根据科迪·格雷(Cody Gray)对此帖子的回答中的出色分析,在滚动条上绘画是不可能的。

也许解决方法可以解决您的问题..?

这个想法是这样的:

您添加一个细线Panel,它可以覆盖滚动条或将其自身附加到其左侧。我应该非常瘦并且超过滚动条的高度;它会通过通常的 Paint 事件重新绘制。

您保留一个行列表,应显示其标记。该列表是根据以下情况重新创建或维护的:

  • 添加和删​​除Rows
  • 更改目标行
  • 可能在排序或过滤时

这是一些代码,只是一个快速的概念证明。为了获得更强大的解决方案,我想我会创建一个装饰器类来DataGridView注册。

现在,当您将电梯移向标记时,您将找到目标行。有很大的改进空间,但我认为这是一个开始..

您必须isRowMarked()根据需要更改功能。我选择测试第一个单元格的背景色..

您还可以轻松地为不同的标记使用不同的颜色;也许通过从标记的行/单元格复制它们。

public Form1()
{
    InitializeComponent();

    dataGridView1.Controls.Add(indicatorPanel);
    indicatorPanel.Width = 6;
    indicatorPanel.Height = dataGridView1.ClientSize.Height - 39;
    indicatorPanel.Top = 20;
    indicatorPanel.Left = dataGridView1.ClientSize.Width - 21;
    indicatorPanel.Paint += indicatorPanel_Paint;
    dataGridView1.Paint += dataGridView1_Paint;
}

Panel indicatorPanel = new Panel();
List<DataGridViewRow> tgtRows = new List<DataGridViewRow>();

void dataGridView1_Paint(object sender, PaintEventArgs e)
{
    indicatorPanel.Invalidate();
}

void indicatorPanel_Paint(object sender, PaintEventArgs e)
{   // check if there is a HScrollbar
    int hs = ((dataGridView1.ScrollBars & ScrollBars.Vertical) != ScrollBars.None ? 20 : 0);

    e.Graphics.FillRectangle(Brushes.Silver, indicatorPanel.ClientRectangle);
    foreach (DataGridViewRow tRow in tgtRows)
    {
        int h = (int)(1f * (indicatorPanel.Height - 20 + hs) * tRow.Index 
                         / dataGridView1.Rows.Count);
        e.Graphics.FillRectangle(Brushes.Red, 0, h-3, 6, 4);
    }
}

bool isRowMarked(DataGridViewRow row)
{
    return row.Cells[0].Style.BackColor == Color.Red;  // <<-- change!
}

// call in: dataGridView1_RowsRemoved, dataGridView1_RowsAdded
// also whenever you set or change markings and after sorting or a filtering
void findMarkers()
{
    tgtRows.Clear();
    foreach (DataGridViewRow row in dataGridView1.Rows)
        if (isRowMarked(row) ) tgtRows.Add(row); 
    indicatorPanel.Invalidate();
}
Run Code Online (Sandbox Code Playgroud)

请注意,我删除了第一个答案,因为原始要求谈论的是“分数”而不仅仅是“一些分数”。现在,第二个版本对我来说似乎好多了。