2009-02-11 43 views

Respuesta

13

Esto podría ser un poco hacky pero se puede hacer:

listView.Items[0].Bounds.Top 

Esto sólo funcionará si sólo hay un elemento de la lista. Por lo tanto, es posible que desee agregar uno temporalmente cuando cree la lista por primera vez y mantenga el valor de la altura.

Si no, siempre se puede utilizar:

listView.TopItem.Bounds.Top 

Para hacer la prueba en cualquier momento, pero todavía se necesitan por lo menos un elemento de la lista.

+1

Resulta que si el elemento se desplaza fuera del área visible, este enfoque no va a funcionar correctamente. – EricLaw

11

A continuación, se indica cómo obtener la altura del encabezado de la vista de lista utilizando llamadas de interoperabilidad de Win32.

[Serializable, StructLayout(LayoutKind.Sequential)] 
public struct RECT 
{ 
    public int Left; 
    public int Top; 
    public int Right; 
    public int Bottom; 
} 

const long LVM_FIRST = 0x1000; 
const long LVM_GETHEADER = (LVM_FIRST + 31); 

[DllImport("user32.dll", EntryPoint="SendMessage")] 
private static extern IntPtr SendMessage(IntPtr hwnd, long wMsg, long wParam, long lParam); 

[DllImport("user32.dll")] 
private static extern bool GetWindowRect(HandleRef hwnd, out RECT lpRect); 

RECT rc = new RECT(); 
IntPtr hwnd = SendMessage(ListView1.Handle, LVM_GETHEADER, 0, 0); 
if (hwnd != null) 
{ 
    if (GetWindowRect(new HandleRef(null, hwnd), out rc)) 
    { 
     int headerHeight = rc.Bottom - rc.Top; 
    } 
} 
+0

¿No deberían los wParam y lParam aquí también ser IntPtr para funcionar correctamente en x64? Probablemente no importe ya que está pasando ceros, pero alguien va a copiar/pegar esto en algún lugar que pueda. – EricLaw

0

verificado esto funciona en mi aplicación Win32 ++:

CHeader* hdr = GetHeader(); 
CRect rcHdr = hdr->GetWindowRect(); 

de altura del cabezal es rcHdr.Height()

2

@Phaedrus

..long hace mucho tiempo .. pero: PInvokeStackImbalance se llama

La firma de SendMessage es (tiempo = Uint32!):

LRESULT WINAPI SendMessage(
    _In_ HWND hWnd, 
    _In_ UINT Msg, 
    _In_ WPARAM wParam, 
    _In_ LPARAM lParam 
) 

Cambiar todo para:

const UInt32 LVM_FIRST = 0x1000; 
const UInt32 LVM_GETHEADER = (LVM_FIRST + 31); 

[Serializable, System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] 
public struct RECT 
{ 
    public int Left; 
    public int Top; 
    public int Right; 
    public int Bottom; 
} 

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] 
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 
[System.Runtime.InteropServices.DllImport("user32.dll")] 
private static extern bool GetWindowRect(System.Runtime.InteropServices.HandleRef hwnd, out RECT lpRect); 

int youtFuncToGetHeaderHeight() 
{ 
    RECT rc = new RECT(); 
    IntPtr hwnd = SendMessage((IntPtr)this.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero); 
    if (hwnd != null) 
    { 
     if (GetWindowRect(new System.Runtime.InteropServices.HandleRef(null, hwnd), out rc)) 
     { 
      int headerHeight = rc.Bottom - rc.Top; 
     } 
    } 
    return -1; 
} 
0

código correcto:

 [Serializable, StructLayout(LayoutKind.Sequential)] 
    public struct RECT 
    { 
     public int Left; 
     public int Top; 
     public int Right; 
     public int Bottom; 
    } 

    const int LVM_FIRST = 0x1000; 
    const int LVM_GETHEADER = (LVM_FIRST + 31); 

    [DllImport("user32.dll", EntryPoint="SendMessage")] 
    private static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); 

    [DllImport("user32.dll")] 
    private static extern bool GetWindowRect(HandleRef hwnd, out RECT lpRect); 

    RECT rc = new RECT(); 
    IntPtr hwnd = SendMessage(ListView1.Handle, LVM_GETHEADER, 0, 0); 
    if (hwnd != null) 
    { 
     if (GetWindowRect(new HandleRef(null, hwnd), out rc)) 
     { 
      int headerHeight = rc.Bottom - rc.Top; 
     } 
    } 
Cuestiones relacionadas