Steph. wrote:
I have a List view displaying data in Detail mode with several columns.
How I can get the column index the user clicked on ? (when user click on
an item inside the ListView, not on a column hearder..)
Thanks for any help !
Steph.
You can use the sub item hittest of the listview. The code below also
takes care about column reordering.
[StructLayout(La youtKind.Sequen tial)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("User 32.dll")]
private static extern int SendMessage(Int Ptr hWnd,
int msg , int wParam , ref RECT lParam);
[DllImport("User 32.dll")]
private static extern int SendMessage(Int Ptr hWnd,
int msg , int wParam , int[] lParam);
private bool HitTest(ListVie w mListView, Point hitPoint,
out int row, out int column)
{
const int LVM_GETSUBITEMR ECT = 0x1038; //Is LVM_FIRST (0x1000) + 56
const int LVM_COLUMNORDER ARRAY = 0x103B;//Is LVM_FIRST (0x1000)+59
const int LVIR_BOUNDS = 0;
bool retval = false;
RECT subItemRect;
row = column = -1;
ListViewItem item = mListView.GetIt emAt(hitPoint.X , hitPoint.Y);
if(item != null && mListView.Colum ns.Count > 1)
{
if(mListView.Al lowColumnReorde r)
{
int[] columnOrder = new int[mListView.Colum ns.Count];
// Get the order of columns in case
// they've changed from the user.
if(SendMessage( mListView.Handl e,
LVM_COLUMNORDER ARRAY, mListView.Colum ns.Count,
columnOrder) != 0)
{
int i;
// Get the subitem rectangles (except column 0),
// but get them in the proper order.
RECT[] subItemRects = new RECT[mListView.Colum ns.Count];
for(i = 1; i < mListView.Colum ns.Count; i++)
{
subItemRects[columnOrder[i]].top = i;
subItemRects[columnOrder[i]].left = LVIR_BOUNDS;
SendMessage(mLi stView.Handle,
LVM_GETSUBITEMR ECT, item.Index,
ref subItemRects[columnOrder[i]]);
}
// Find where column 0 is.
for(i = 0; i < columnOrder.Len gth; i++)
if(columnOrder[i] == 0)
break;
// Fix column 0 since we can't get
// the rectangle bounds of it using above.
if(i > 0)
{
// If column 0 not at index 0, set using the previous.
subItemRects[i].left = subItemRects[i-1].right;
subItemRects[i].right = subItemRects[i].left
+ mListView.Colum ns[0].Width;
}
else
{
// Else, column 0 is at index 0, so use the next.
subItemRects[0].left = subItemRects[1].left -
mListView.Colum ns[0].Width;
subItemRects[0].right = subItemRects[1].left;
}
// Go through the subitem rectangle bounds and
// see where our point is.
for(int index = 0; index < subItemRects.Le ngth; index++)
{
if(hitPoint.X >= subItemRects[index].left &
hitPoint.X <= subItemRects[index].right)
{
row = item.Index;
column = columnOrder[index];
retval = true;
break;
}
}
}
}
// No column reordering...mu ch simpler.
else
{
for(int index = 1; index <= mListView.Colum ns.Count-1;
index++)
{
subItemRect = new RECT();
subItemRect.top = index;
subItemRect.lef t = LVIR_BOUNDS;
if(SendMessage( mListView.Handl e,
LVM_GETSUBITEMR ECT, item.Index, ref subItemRect) != 0)
{
if(hitPoint.X < subItemRect.lef t)
{
row = item.Index;
column = 0;
retval = true;
break;
}
if(hitPoint.X >= subItemRect.lef t & hitPoint.X <=
subItemRect.rig ht)
{
row = item.Index;
column = index;
retval = true;
break;
}
}
}
}
}
return retval;
}
HTH,
Andy
--
To email me directly, please remove the *NO*SPAM* parts below:
*NO*SPAM*xmen40 @*NO*SPAM*gmx.n et