Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Listview中获取选定的子项索引并将其高亮显示?_C#_.net_Winforms_Listview_Selection - Fatal编程技术网

C# 如何在Listview中获取选定的子项索引并将其高亮显示?

C# 如何在Listview中获取选定的子项索引并将其高亮显示?,c#,.net,winforms,listview,selection,C#,.net,Winforms,Listview,Selection,我正在尝试获取选定的ListViewItem索引,以便当用户单击特定行(如第2行)时,我希望将单击的单元格文本设置为文本框文本 我还希望仅突出显示此单元格,理想情况下使用ListView使用的常规选择,还是需要创建一个从ListView继承的类来执行此操作 大概是这样的: 您可以自己绘制所选的所有者,绘制控件(集合),然后处理ListView.DrawSubItem事件。 ListView.DrawColumnHeader事件可以使用默认值 ► 因为这是默认的渲染器,所以我使用。如果使用Gra

我正在尝试获取选定的ListViewItem索引,以便当用户单击特定行(如第2行)时,我希望将单击的单元格文本设置为文本框文本

我还希望仅突出显示此单元格,理想情况下使用ListView使用的常规选择,还是需要创建一个从ListView继承的类来执行此操作

大概是这样的:

您可以自己绘制所选的所有者,绘制控件(集合),然后处理
ListView.DrawSubItem
事件。
ListView.DrawColumnHeader
事件可以使用默认值

► 因为这是默认的渲染器,所以我使用。如果使用
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();

或者,您可以在通知鼠标交互时更改子项的颜色(此处,使用
MouseDown
事件)并保存以前的状态(仅此处的颜色)。最好保存状态,因为每个子项都可以有自己的设置,所以不能只恢复到父ListViewItem或ListView值

如上所述,请在每个父ListViewItem中设置,否则将忽略颜色设置。
此外,必须设置为
false
,否则将毫无意义:)

在这里,状态保存在一个可为空的元组字段中,
(ListViewSubItem,Color[])
。一个类对象可能更好,它只是更短

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);
    }
}
这就是它的工作原理:


► 关于项目/子项目索引,如问题中所述:

检索
列表视图项时
/
子项
单击

那么ListViewItem索引当然是:

var itemIndex = hitTest.Item.Index;
子项索引是:

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

为什么不使用
DataGridView
?@RezaAghaei:我没有想到要使用DGV,我想为了简单起见,我更多地使用ListView。从.NET 2.0开始,我再也没有使用ListView来显示这样的列表。假设您有一个项目列表,那么在DataGridView中显示它们就像
dataGridView1.DataSource=list一样简单或您将在此处执行的操作非常简单,如
dataGridView1.SelectionMode=DataGridViewSelectionMode.CellSelect。我认为最好将它视为您未来应用程序的一种选择:以同样的方式更新ListView中的一个单元格,您可以在DATAGRIDVIEW中这样做,甚至更好(使用数据绑定)。除了琼之外,您不应该删除POST,也许其他人也会发现它有用。
var subItemIndex = hitTest.Item.SubItems.IndexOf(hitTest.SubItem);