鼠标悬停时C#更改表行颜色 [英] C# change table row color when mouse hover

查看:104
本文介绍了鼠标悬停时C#更改表行颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的winform中有一个表格布局面板,我想每当鼠标悬停一行时就在行中添加一种效果.

我认为我需要对表进行Mouse_over操作,然后检测表的行号,然后迭代该行上的每个单元格并更改其背景色.

问题是我不知道如何获取行号.

请问有什么想法吗?

我正在向表中动态添加行,有一组按钮,当我单击其中的一组按钮时,它将删除表中的所有旧行,并添加与此按钮相关的新行.这是我添加新行的方式:

  tlp.RowCount ++;tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));tlp.Controls.Add(new Label(){...},cellIDX,rowIDX);//添加更多列// 

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

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

解决方案

您可以执行以下操作:

因为实际上有

注意:当您动态地添加控件时,您还需要进行连接.这是一个示例:

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

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

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

为此,您需要添加到项目中,进行编译,检查以查看它是否出现在工具箱中.如果您愿意,可以只更改form_designer类中的两个子对象.

I have a table layout panel in my winform, and I want to add an effect to the rows whenever the mouse is hover a row.

I think I need to make a Mouse_over action over the table, and then detect the row number of the table, and then iterate on each cell on the row and change it's back color.

The problem is that I don't know how to get the row number.

Any ideas please?

EDIT: I am adding rows to the table dynamically, I have set of buttons and when I click one it deletes all old rows from the table and adds new rows that are related to this button. This is the way I add new rows:

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

and to remove old rows I loop through all rows from bottom to top, removes all related controls of current cell, then I remove style and row num like so:

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

解决方案

Here is what you can do:

As there actually are no Cells in a TableLayouPanel all you can do is

  • detect where th mouse is
  • paint the TLP in the CellPaint event.

Since your TLP most likely will contain controls they also need to detect whether the mouse is on them..

Here is an example:

First a class level variable to store the current row:

 int tlpRow = -1;

Next a CellPaint event that can color a row:

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

Next we need detection routines. First one for the 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;
}

It loops over all rows and adds up the heights until it has found the right one. Then it stores the row index and triggers the CellPaint event.

We can use the same routine for the controls:

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

We simply calculate the mouse position relative to the TLP and call the same test.

Note that this test only for 1 level of nesting. If you have deeper nested control you may need to expand on the test somewhat..!

We also need to call the tests; the TLP test can be called in the MouseMove:

private void tableLayoutPanel1_MouseMove(object sender, MouseEventArgs e)
{
    testTLP(tableLayoutPanel1, e.Location);
}

The controls get hooked up all together maybe like this:

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

I use the MouseMove event as the MouseEnter sometimes slipped through in my tests..

If you add controls later you need to hook the up as well. Make sure not to hook one up multiple times!

Most likely you want to reset the coloring when leaving the TLP:

private void tableLayoutPanel1_MouseLeave(object sender, EventArgs e)
{
    Point tplPoint = tableLayoutPanel1.PointToClient(Control.MousePosition);
    if (!tableLayoutPanel1.ClientRectangle.Contains(tplPoint))  tlpRow = -1;
    tableLayoutPanel1.Invalidate();
}

Result:

Note: when you add Controls dynamically you need to hook the up as well. Here is an example:

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

If you find the coloring flickers you can simply add a DoubleBuffered subclass:

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

To do so you need to add to the project, compile, check to see it appears in the ToolBox. If you want to you can simply change the two sponts in the form_designer class..

这篇关于鼠标悬停时C#更改表行颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆