gpt4 book ai didi

c# - 无论如何确定ListView中Column左上角的坐标?

转载 作者:太空狗 更新时间:2023-10-29 23:32:03 25 4
gpt4 key购买 nike

我找不到任何可以帮助我解决这个问题的函数,我不想编写疯狂的函数来对 ListView 区域的每个像素进行 HitTest,以找出所需 Column 的坐标(如果有可能获得 Column来自 HitTest)。

enter image description here

感谢 Yair Nevet 的评论,我编写了下一个函数来确定所需列的左侧位置:

private int GetLeftOfColumn(ColumnHeader column, ListView lv)
{
if (!lv.Columns.Contains(column))
return -1;

int calculated_left = 0;

for (int i = 0; i < lv.Columns.Count; i++)
if (lv.Columns[i] == column)
return calculated_left;
else
calculated_left += lv.Columns[i].Width + 1;

return calculated_left;
}

最佳答案

因为上面提到了 USER32 消息但没有给出实现,我只是在需要解决它时遇到这个问题,这里有一个使用消息传递到 native 代码的工作版本。

下面是封装在私有(private) NativeMethods 类中的一些必需项:

private static class NativeMethods {
private const int LVM_FIRST = 0x1000;
private const int LVM_GETHEADER = LVM_FIRST + 31;

private const int HDM_FIRST = 0x1200;
private const int HDM_GETITEMRECT = HDM_FIRST + 7;

private const int SB_HORZ = 0;
private const int SB_VERT = 1;

private const int SIF_POS = 0x0004;

[StructLayout(LayoutKind.Sequential)]
public class SCROLLINFO {
public int cbSize = Marshal.SizeOf(typeof(NativeMethods.SCROLLINFO));
public int fMask;
public int nMin;
public int nMax;
public int nPage;
public int nPos;
public int nTrackPos;
}

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

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageGETRECT(IntPtr hWnd, int Msg, int wParam, ref RECT lParam);

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool GetScrollInfo(IntPtr hWnd, int fnBar, SCROLLINFO scrollInfo);

/// <summary>
/// Return the handle to the header control on the given list
/// </summary>
/// <param name="list">The listview whose header control is to be returned</param>
/// <returns>The handle to the header control</returns>
public static IntPtr GetHeaderControl(ListView list) {
return SendMessage(list.Handle, LVM_GETHEADER, 0, 0);
}

/// <summary>
/// Get the scroll position of the given scroll bar
/// </summary>
/// <param name="lv"></param>
/// <param name="horizontalBar"></param>
/// <returns></returns>
public static int GetScrollPosition(ListView lv, bool horizontalBar) {
int fnBar = (horizontalBar ? SB_HORZ : SB_VERT);

SCROLLINFO scrollInfo = new SCROLLINFO();
scrollInfo.fMask = SIF_POS;
if (GetScrollInfo(lv.Handle, fnBar, scrollInfo)) {
return scrollInfo.nPos;
}
else {
return -1;
}
}

/// <summary>
/// Return the screen rectangle of the column header item specified
/// </summary>
/// <param name="handle">Handle to the header control to check</param>
/// <param name="index">Index of the column to get</param>
/// <returns></returns>
public static Rectangle GetHeaderItemRect(IntPtr handle, int index) {
RECT rc = new RECT();
IntPtr result = NativeMethods.SendMessageGETRECT(handle, HDM_GETITEMRECT, index, ref rc);
if (result != IntPtr.Zero) {
return new Rectangle(rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top);
}
return Rectangle.Empty;
}
}

这是获取您的位置的代码:

/// <summary>
/// Get's the location coordinate of the specified column header's top/left corner
/// </summary>
/// <param name="oListView">ListView control to get the column header location from</param>
/// <param name="iColumn">Column to find the location for</param>
/// <param name="bAsScreenCoordinate">Whether the location returned is for the screen or the local ListView control</param>
/// <returns>Location of column header or <see cref="Point.Empty"/> if it could not be retrieved</returns>
public static Point GetColumnHeaderTopLeft(this ListView oListView, int iColumn, bool bAsScreenCoordinate) {
if (oListView == null) {
throw new ArgumentNullException();
}
if ((iColumn < 0) || (iColumn >= oListView.Columns.Count)) {
throw new ArgumentOutOfRangeException();
}

// Get the header control's rectangle
IntPtr hndHeader = NativeMethods.GetHeaderControl(oListView);
Rectangle oHeaderRect = NativeMethods.GetHeaderItemRect(hndHeader, iColumn);
if (oHeaderRect.IsEmpty) {
return Point.Empty;
}

// Get the scroll bar position to adjust the left
int iScroll = NativeMethods.GetScrollPosition(oListView, true);

// Create the local coordinate
Point oLocation = new Point(oHeaderRect.Left - iScroll, oHeaderRect.Top);

// Return the local or screen coordinate
return bAsScreenCoordinate ? oListView.PointToScreen(oLocation) : oLocation;
}

关于c# - 无论如何确定ListView中Column左上角的坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17642308/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com