c# - Hide Windows Forms ListView Column in Details View without deleting Column or resizing it to Zero -
i have in c# net 2.0 windows forms listview ten columns filled data @ startup of application. data huge, cannot reloaded fast in-between. listview has details view on , allows user resizing of each column separately.
the user shall able hide of ten columns or multiple of them @ once , unhide columns again time in non-specific row. data shall not deleted while hiding column.
following things have tried result not satisfying:
1) resizing column size 0 make disappearing until user starts play columns. user accidently resize them because in listview there option allowed user resize each column manually.
2) deleting column out occurs following problem: when try add column back, column doesn't remember position , size. position main problem, i'll try explain why. if user decides first hide "column 2" , "column 3" , user later unhides 3 before 2, "index 2" doesn't exist, cannot insert @ index no. 3 , exception rises. if remember index position before deleting cannot put column index, because don't know if previous columns hided or column missing before , after or hided or not. scenario that: 1 shown, 2 hided, 3 hided too, 4 shown, 5 hided, 6 hided, 7 hided , 8 shown, 9 hided, 10 hided.
possible solutions "1)" , "2)" automatically out ruled in scenario. better making width of column zero, since user shall able resize columns time need, resizing 0 cannot hided user. user unhide resize , system think it's still hidden etc. etc. , looks not professional if hidden columns can "resized back" or how name else.
has better idea? why listview column has no "visible" or "hide" property, wonder? if did before please post solution.
i have add use autoresizing of columns in listview when data being added. reason answer below doesn't work. resize event can't detect width of -1. "all invisible columns" width 0 resized back, when data added. since listview cuts out data overlaps column length, need autoresize permanently. explorer has not problem because fits columns length of data. c# has not such advanced listview, here have set columns -1 each time when data being added. in conception doesn't work idea of column.width = 0 hiding columns.
ok, problem in fact how hide listview column?. has been asked many many people on web. i've tried searching many couldn't find anything. i've ended solution: set column width zero. work trick here:
//this try hiding column @ index 1 listview1.columns[1].width = 0; //columnwidthchanging event handler of listview private void listview1_columnwidthchanging(object sender, columnwidthchangingeventargs e){ if(e.columnindex == 1){ e.cancel = true; e.newwidth = 0; } }
it works perfectly. when user moves mouse on pipe
@ position of hidden column, there cursor
indicator appearing notify user there zero-width column here, hold mouse down , drag resize it. of course, user can't resize zero because cancel
, make newwidth = 0
(as code above does). cursor
notifying such operation makes little nasty, here screen shot demonstrating problem:
to solve problem not easy. @ least that's feel. thought of solution seems work ok. idea have detect if mouse on near pipe of hidden column, have set cursor = cursors.arrow
. here whole class think works great you:
public class customlistview : listview { [dllimport("user32")] private static extern bool enumchildwindows(intptr parenthwnd, enumchildproc proc, object lparam); delegate bool enumchildproc(intptr childhwnd, object lparam); public customlistview() { visiblechanged += (s, e) => { if (visible && headerhandle == intptr.zero&&!designmode) { enumchildwindows(handle, enumchild, null); headerproc = new headerproc(this); headerproc.assignhandle(headerhandle); } }; columnpipelefts[0] = 0; } //save handle column headers, listview has child window used render column headers intptr headerhandle; //this used use hook message loop of column headers headerproc headerproc; private bool enumchild(intptr childhwnd, object lparam) { headerhandle = childhwnd; return true; } //updated code protected override void wndproc(ref message m) { if (m.msg == 0x101e&&hiddencolumnindices.contains(m.wparam.toint32()))//wm_setcolumnwidth = 0x101e { if(m.lparam.toint32() > 0) hiddencolumnwidths[m.wparam.toint32()] = m.lparam.toint32(); return;//discard message changing hidden column width won't shown again. } base.wndproc(ref m); } //save column indices hidden list<int> hiddencolumnindices = new list<int>(); //save width of hidden columns dictionary<int, int> hiddencolumnwidths = new dictionary<int, int>(); //save left (x-position) of pipes separate column headers. dictionary<int, int> columnpipelefts = new dictionary<int, int>(); protected override void oncolumnwidthchanging(columnwidthchangingeventargs e) { if (hiddencolumnindices.contains(e.columnindex)) { e.cancel = true; e.newwidth = 0; } base.oncolumnwidthchanging(e); } //we need update columnpipelefts whenever width of column changes protected override void oncolumnwidthchanged(columnwidthchangedeventargs e) { base.oncolumnwidthchanged(e); updatecolumnpipelefts(columns[e.columnindex].displayindex + 1); } int index = -1; protected override void oncolumnreordered(columnreorderedeventargs e) { int = math.min(e.newdisplayindex, e.olddisplayindex); index = index != -1 ? math.min(i + 1, index) : + 1; base.oncolumnreordered(e); } //this used update columnpipelefts every reordering columns or resizing columns. private void updatecolumnpipelefts(int fromindex) { int w = fromindex > 0 ? columnpipelefts[fromindex - 1] : 0; (int = fromindex; < columns.count; i++) { w += > 0 ? columns.oftype<columnheader>().where(k=>k.displayindex == - 1).single().width : 0; columnpipelefts[i] = w; } } //this used hide column columnheader passed in public void hidecolumn(columnheader col) { if (!hiddencolumnindices.contains(col.index)) { hiddencolumnwidths[col.index] = col.width;//save current width restore later col.width = 0;//hide column hiddencolumnindices.add(col.index); } } //this used hide column column index passed in public void hidecolumn(int columnindex) { if (columnindex < 0 || columnindex >= columns.count) return; if (!hiddencolumnindices.contains(columnindex)) { hiddencolumnwidths[columnindex] = columns[columnindex].width;//save current width restore later columns[columnindex].width = 0;//hide column hiddencolumnindices.add(columnindex); } } //this used show column columnheader passed in public void showcolumn(columnheader col) { hiddencolumnindices.remove(col.index); if(hiddencolumnwidths.containskey(col.index)) col.width = hiddencolumnwidths[col.index];//restore width show column hiddencolumnwidths.remove(col.index); } //this used show column column index passed in public void showcolumn(int columnindex) { if (columnindex < 0 || columnindex >= columns.count) return; hiddencolumnindices.remove(columnindex); if(hiddencolumnwidths.containskey(columnindex)) columns[columnindex].width = hiddencolumnwidths[columnindex];//restore width show column hiddencolumnwidths.remove(columnindex); } //the helper class allows hook message loop of column headers private class headerproc : nativewindow { [dllimport("user32")] private static extern int setcursor(intptr hcursor); public headerproc(customlistview listview) { this.listview = listview; } bool mousedown; customlistview listview; protected override void wndproc(ref message m) { if (m.msg == 0x200 && listview!=null && !mousedown) { int x = (m.lparam.toint32() << 16) >> 16; if (isspottedonanyhiddencolumnpipe(x)) return; } if (m.msg == 0x201) { mousedown = true; int x = (m.lparam.toint32() << 16) >> 16; isspottedonanyhiddencolumnpipe(x); } if (m.msg == 0x202) mousedown = false; if (m.msg == 0xf && listview.index != -1 && mousebuttons == mousebuttons.none) { //wm_paint = 0xf listview.updatecolumnpipelefts(listview.index); listview.index = -1; }; base.wndproc(ref m); } private bool isspottedonanyhiddencolumnpipe(int x) { foreach (int in listview.hiddencolumnindices.select(j=>listview.columns[j].displayindex)) { if (x > listview.columnpipelefts[i] - 1 && x < listview.columnpipelefts[i] + 15) { setcursor(cursors.arrow.handle); return true; } } return false; } } }
Comments
Post a Comment