簡體   English   中英

鼠標懸停時C#更改表行顏色

[英]C# change table row color when mouse hover

我的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--;

您可以執行以下操作:

由於TableLayouPanel實際上沒有Cells所以您所能做的就是

  • 檢測鼠標在哪里
  • CellPaint事件中繪制TLP

由於您的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級嵌套。 如果您有更深層的嵌套控件,則可能需要對測試進行一些擴展。

我們還需要調用測試; 可以在MouseMove調用TLP測試:

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

結果:

在此處輸入圖片說明

注意: 動態添加控件時,還需要進行連接。 這是一個例子:

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

為此,您需要添加到項目中,進行編譯,檢查以查看它是否出現在工具箱中。 如果需要,您可以簡單地更改form_designer類中的兩個子對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM