鼠标悬停时C#更改表格行颜色

时间:2016-09-04 12:01:07

标签: c# .net winforms

我的winform中有一个表格布局面板,我想在鼠标悬停一行时为行添加效果。

我想我需要在表上执行Mouse_over操作,然后检测表的行号,然后迭代行上的每个单元格并将其更改为背面颜色。

问题在于我不知道如何获取行号。

有什么想法吗?

编辑:我正在动态地向表中添加行,我有一组按钮,当我单击一个按钮时,它会从表中删除所有旧行,并添加与此按钮相关的新行。 这是我添加新行的方式:

tlp.RowCount++;
tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tlp.Controls.Add(new Label() { ... }, cellIDX, rowIDX);
// adding more columns //

并删除旧行我从下到上遍历所有行,删除当前单元格的所有相关控件,然后我删除样式和行num,如下所示:

tlp.RowStyle.RemoveAt(rowNum);
tlp.RowCount--;

1 个答案:

答案 0 :(得分:3)

以下是您可以做的事情:

实际上no Cells in a TableLayouPanel实际上只有<{p}}

  • 检测鼠标在哪里
  • TLP事件中绘制CellPaint

由于您的TLP最有可能包含控件,因此他们还需要检测鼠标是否在其上..

以下是一个例子:

首先是一个用于存储当前行的类级变量:

 int tlpRow = -1;

接下来可以为行着色的CellPaint事件:

private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
    if (e.Row == tlpRow) 
        using (SolidBrush brush = new SolidBrush(Color.FromArgb(123, 234, 45, 67)))
            e.Graphics.FillRectangle(brush, e.CellBounds);
}

接下来我们需要检测例程。第一个是TLP

bool testTLP(TableLayoutPanel tlp,  Point pt)
{
    var rs = tableLayoutPanel1.RowStyles;
    var rh = 0f;
    for (int i = 0; i < rs.Count; i++)
    {
        if (pt.Y > rh && pt.Y <= rh + rs[i].Height )
        {
            if (tlpRow != i)
            {
                tlpRow = i;
                tableLayoutPanel1.Invalidate();
                return true;
            }
        }
        rh += rs[i].Height;
    }
    tlpRow = -1;
    return false;
}

它遍历所有行并累加高度,直到找到正确的行。然后它存储行索引并触发CellPaint事件。

我们可以对控件使用相同的例程:

bool testTLP(TableLayoutPanel tlp)
{
    Point point = tlp.PointToClient(Control.MousePosition);
    return testTLP(tlp, point);
}

我们只是计算相对于TLP的鼠标位置并调用相同的测试。

请注意,此测试仅适用于1级嵌套。如果你有更深层次的嵌套控件,你可能需要在某种程度上扩展测试..!

我们还需要打电话给考试;可以在TLP

中调用MouseMove测试
private void tableLayoutPanel1_MouseMove(object sender, MouseEventArgs e)
{
    testTLP(tableLayoutPanel1, e.Location);
}

控件总是连在一起可能是这样的:

void hookUpControls(TableLayoutPanel tlp)
{
    foreach (Control ctl in tlp.Controls)
    {
        ctl.MouseMove += (s, e) => { testTLP(tlp); };
    }
}

我使用MouseMove事件,因为MouseEnter有时会在我的测试中滑过..

如果您稍后添加控件,则还需要将其连接起来。确保不要多次挂钩!

离开TLP

时,您很可能想要重置着色
private void tableLayoutPanel1_MouseLeave(object sender, EventArgs e)
{
    Point tplPoint = tableLayoutPanel1.PointToClient(Control.MousePosition);
    if (!tableLayoutPanel1.ClientRectangle.Contains(tplPoint))  tlpRow = -1;
    tableLayoutPanel1.Invalidate();
}

结果:

enter image description here

注意:当你添加控件动态时,你也需要连接它。这是一个例子:

Label lbl = new Label() { Text = "newbie" };
lbl.MouseMove += (ss, ee) => { testTLP(tlp, lbl); }; 
tlp.Controls.Add(lbl, cellIDX, rowIDX);

如果你发现着色闪烁,你可以简单地添加一个DoubleBuffered子类:

class DoubleBufferedTLP : TableLayoutPanel
{
    public DoubleBufferedTLP()
    {
        DoubleBuffered = true;
    }
}

为此,您需要添加到项目中,编译,检查它是否出现在ToolBox中。如果你愿意,你可以简单地在form_designer类中更改两个文件..