簡體   English   中英

如何在 Listview 中獲取選定的 SubItem 索引並突出顯示它?

[英]How to get the selected SubItem index in a Listview and highlight it?

我正在嘗試獲取選定的 ListViewItem 索引,以便當用戶單擊特定行(例如第 2 行)時,我希望將單擊的單元格的文本設置為 TextBox 的文本。

我還想僅突出顯示此單元格,理想情況下使用 ListView 使用的常規選擇,或者我是否需要創建一個繼承自 ListView 的 class 來執行此操作?

像這樣的東西:

在此處輸入圖像描述 在此處輸入圖像描述

您可以自己繪制所選的ListViewItem.ListViewSubItem ,所有者繪制控件(設置ListView.OwnerDraw = true ),然后處理ListView.DrawSubItem事件。
ListView.DrawColumnHeader事件可以使用默認值。

▶ 我正在使用TextRenderer ,因為這是默認渲染器。 如果您使用Graphics.DrawText ,您會注意到不同之處。

TextFormatFlags flags = TextFormatFlags.LeftAndRightPadding |
                        TextFormatFlags.VerticalCenter;

private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
    var lv = sender as ListView;
    var subItem = lv.HitTest(lv.PointToClient(MousePosition)).SubItem;

    if (subItem != null && e.SubItem == subItem) {
        using (var brush = new SolidBrush(SystemColors.Highlight)) {
            e.Graphics.FillRectangle(brush, e.SubItem.Bounds);
        }
        TextRenderer.DrawText(e.Graphics, e.SubItem.Text, e.SubItem.Font, 
                              e.Bounds, SystemColors.HighlightText, flags);
    }
    else {
        e.DrawDefault = true;
    }
}

private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e) 
    => e.DrawDefault = true;

// Invalidate on a mouse interaction, otherwise the ListView doesn't redraw the SubItem
private void listView1_MouseUp(object sender, MouseEventArgs e)
    => (sender as ListView).Invalidate();

或者,您可以在通知鼠標交互時更改 SubItem 的 Colors(此處使用MouseDown事件)並保存之前的 state(此處僅為 Z5D50889672F6F860D14F502DE3DE159)。 最好保存 state,因為每個 SubItem 都可以有自己的設置,因此您不能只恢復到父 ListViewItem 或 ListView 值。

如前所述,在每個父 ListViewItem 中設置UseItemStyleForSubItems = false ,否則將忽略 Colors 設置。
此外, FullRowSelect必須設置為false ,否則毫無意義:)

在這里,state 保存在一個可以為空的命名元組字段(ListViewSubItem, Color[])中。
class object 可能更好,只是更短。

private (ListViewItem.ListViewSubItem Item, Color[] colors)? previousItem = null;

private void listView1_MouseDown(object sender, MouseEventArgs e)
{
    var lv = sender as ListView;
    var subItem = lv.HitTest(e.Location).SubItem;

    if (previousItem.HasValue) {
        // If an Item's Colors have been changed, restore the state
        // It removes the selection if you click in an empty area
        previousItem.Value.Item.BackColor = previousItem.Value.colors[0];
        previousItem.Value.Item.ForeColor = previousItem.Value.colors[1];
        lv.Invalidate(previousItem.Value.Item.Bounds);
    }

    if (subItem != null) {
        // Save the SubItem's colors state
        previousItem = (subItem, new[] { subItem.BackColor, subItem.ForeColor });
        // Set new Colors. Here, using the default highlight colors
        subItem.BackColor = SystemColors.Highlight;
        subItem.ForeColor = SystemColors.HighlightText;
        lv.Invalidate(subItem.Bounds);
    }
}

這就是這個東西的工作原理:

ListView 子項選擇


▶ 關於 Item / SubItem 索引,正如問題中提到的:

當您檢索使用ListView.HitTest單擊的ListViewItem / SubItem

 var hitTest = lv.HitTest(e.Location);

那么 ListViewItem 索引當然是:

var itemIndex = hitTest.Item.Index;

SubItem.Index是:

var subItemIndex = hitTest.Item.SubItems.IndexOf(hitTest.SubItem);

暫無
暫無

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

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