简体   繁体   English

如何以编程方式设置列表视图FocusedItem

[英]How to set a listview FocusedItem programatically

How can I set the FocusedItem property programatically? 如何以编程方式设置FocusedItem属性?

I've tried this so far with no success: 到目前为止,我已经尝试过但没有成功:

If lvw.FocusedItem Is Nothing Then
    If lvw.Items.Count > 0 Then
    lvw.Focus()
    lvw.HideSelection = False
    lvw.Items(0).Selected = True
    lvw.Items(0).Focused = True
    lvw.FocusedItem = lvw.Items(0)
    lvw.Select()
    End If
End If

btw the form where the listview is has not called the ShowDialog method yet. 顺便说一句,列表视图所在的表单尚未调用ShowDialog方法。 Can this be the reason for this not to work? 这可能是不起作用的原因吗?

You have to understand that each control on the Form and the Form itself is a window and for the window to have focus it must first be created and assigned a handle. 您必须了解,窗体和窗体本身上的每个控件都是一个窗口,并且要使该窗口具有焦点,必须首先创建该窗口并为其分配一个句柄。

For a basic description of this, I refer you to: All About Handles in Windows Forms The following excerpts are from the referenced article. 有关此内容的基本描述,请参考: Windows窗体中所有关于句柄的内容以下摘录来自引用的文章。

What is a Handle? 什么是手柄?

A handle (HWND) is the return value from CreateWindowEx which the Windows Operating System uses to identify a window. 句柄(HWND)是CreateWindowEx的返回值,Windows操作系统使用它来标识窗口。 A "window" in win32 is a much broader concept than you may think - each individual button, combobox, listbox etc comprises a window. win32中的“窗口”概念比您想象的要广泛得多-每个单独的按钮,组合框,列表框等都包含一个窗口。 (For more information see About Window Classes ) NOTE: there are other things known as "Handles" in the Framework - eg GDI Handles from a Bitmap or Handles to Device Contexts (HDCs) - this article discusses HWNDs only. (有关更多信息,请参见关于窗口类。)注意:框架中还有其他称为“句柄”的事物-例如,从位图的GDI句柄或到设备上下文(HDC)的句柄-本文仅讨论HWND。

... ...

When does a Control create its handle? 控件何时创建其句柄? (When does a control call CreateWindowEx?) (控件何时调用CreateWindowEx?)

A control tries as much as possible to defer creating its handle. 控件尝试尽可能地推迟创建其句柄。 This is because setting properties forces chatty interop between the CLR and user32. 这是因为设置属性会强制CLR和user32之间进行健谈互操作。

Typically the handles for all the controls are created before the Form.Load event is called. 通常,所有控件的句柄都是在调用Form.Load事件之前创建的。 Handles can also be created if the "Handle" property is called and the handle has not yet been created, or CreateControl() is called. 如果调用了“ Handle”属性并且尚未创建该句柄,或者已调用CreateControl(),则也可以创建句柄。

So a window's handle is not immediately created when you instantiate a control. 因此,实例化控件时不会立即创建窗口的句柄。 However, you can force a control to create its handle by referencing its Handle property . 但是,您可以通过引用其Handle属性来强制控件创建其句柄。

So if you first get the ListView to create its handle, then when you set those properties that you wanted. 因此,如果首先获取ListView来创建其句柄,那么当您设置所需的属性时。

Dim f2 As New Form2
' you do not need this condition, it is here only for demonstration purposes
' so that you can step through the code in the debugger and observe the
' code execution.
If Not f2.ListView1.IsHandleCreated Then
   ' retrieval of the Handle will cause a handle to be created
   ' if it has not yet been created
   ' if you delete the If-Then block, you will need to retain the 
   ' following statement

   Dim h As IntPtr = f2.ListView1.Handle
End If

f2.ListView1.FocusedItem = f2.ListView1.Items(2)
f2.ListView1.Items(2).Selected = True
f2.ListView1.Items(2).Focused = True
f2.ActiveControl = f2.ListView1
f2.ShowDialog()

As others have commented, your code should work as written. 正如其他人所评论的那样,您的代码应按书面形式工作。 If all you need is to programmatically access the focused item in your code, you shouldn't be experiencing any difficulties. 如果您所需要做的就是以编程方式访问代码中的重点项目,那么您应该不会遇到任何困难。 (If you are, please describe them.) (如果是,请描述一下。)

If you are looking for a visual effect (the row being highlighted), my guess is that your code is in another control's event and the focus is being set back to that control automatically the instant after your code runs. 如果您正在寻找视觉效果(该行突出显示),我想您的代码在另一个控件的事件中,并且焦点将在代码运行后立即自动重新设置为该控件。 More than likely your code needs to be where it is and trying to move it elsewhere to prevent this issue would be a waste of time. 您的代码很有可能需要放在原处,而尝试将其移至其他位置以防止出现此问题将浪费时间。

However, there are other ways to set a row apart visually. 但是,还有其他方法可以在视觉上分隔行。 When a list view isn't likely to stay focused, my preferred method is to distinguish the selected item with a different fore/back color. 当列表视图不太可能保持聚焦时,我的首选方法是用不同的前后颜色区分所选项目。 (You can use the focused item if you prefer, but I find the selected item more useful. Your call.) (您可以根据需要使用重点突出的项目,但我发现所选项目更有用。您可以致电。)

Here is an example which visually highlights the selected row, regardless of focus: 这是一个示例,该示例以可视方式突出显示选定的行,而与焦点无关:

Private Sub lvw_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lvw.SelectedIndexChanged
    If lvw.Items Is Nothing Then Exit Sub
    For Each lvi As ListViewItem In lvw.Items
        If lvi.Selected = True Then
            lvi.ForeColor = Color.DarkGray
            lvi.BackColor = Color.LightCyan
        Else
            lvi.ForeColor = Color.Black
            lvi.BackColor = Color.White
        End If
    Next
End Sub

EDIT: 编辑:

In response to the added information that this form is being displayed using ShowDialog , yes, that is likely the source of your problem. 响应于使用ShowDialog显示此表单的附加信息, 是的,这很可能是问题的根源。

ShowDialog creates a new instance of the form. ShowDialog创建表单的新实例 Therefore, if you have set any properties of a form or its controls, and later call ShowDialog to display that form, the form displayed is a new copy of the original form and will not reflect the changes you made programatically. 因此,如果您设置了表单或其控件的任何属性,然后再调用ShowDialog来显示该表单,则显示的表单是原始表单的新副本,并且不会反映您以编程方式进行的更改。

Imagine you sit down at a computer where a blank Word document is already open. 想象一下,您坐在一台空白Word文档已经打开的计算机上。 You type something in it and then open a new document. 您在其中键入一些内容,然后打开一个新文档。 The text you typed in the first document is not copied to the second. 您在第一个文档中键入的文本不会复制到第二个文档中。 I think this is the root of your troubles here. 我认为这是您在这里遇到麻烦的根源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM