In-Place editing of listview subitems

Source: Internet
Author: User

Http://www.codeproject.com/cs/miscctrl/ListViewCellEditors.asp
In-Place editing of listview subitems

Download source files (including Demo Application)-31.2 KB

Introduction

While talking with one of our MERs, he wanted an additional feature in one of our programs to let him drop a number of files onto our application and then modify certain properties of the resulting documents in a list.

Showing these documents inListViewCan be done easily, but editing of single properties requires a little work (since built-inListViewOnly allows plain editing ofListViewItem'S text). Because I didn't find anything pre-built, I decided to write my own in-place editingListViewS, so here it is...

How it is done

In fact, in-place editing inListViewIsn't too much magic, but there are a few places where the plain. NET Framework classes aren't sufficient, so I had to use a little InterOP.

Only the General. NET Framework class does not work. Some internal operations must be performed.

First, you have to have a control to perform the actual editing ofSubItem. Which control you use is (almost) completely up to you.TextBox,ComboBoxOrDateTimePickerWorks fine, for example. Since this control is used only whenSubItemHas been clicked, it shoshould be invisible in the beginning.

First, we must have a control to actually edit the subitem. We usually use Textbox,ComboBoxOrDateTimePicker.

These controls are invisible at first and can be used only when subitem is clicked.

Then you have to find out whichSubItemHas been clicked. This part is quite straightforward, I 've added a methodGetSubItemAt()To myListViewExTo make things a little easier.

You must find that the subitem has been clicked. This part is quite understandable. I have added getsubitemat () to my listviewex to simplify the operation.

A little twist comes from column reordering. StandardListViewAllows you to rearrange its columns while in report view (AllowColumnReorderProperty). Unfortunately, there is no built-in way to find out the current order of your columns, so this is where InterOP came in handy:

Another problem is that columns are re-sorted. The standard listview control allows you to re-sort the columns in the report view. unfortunately, there is no built-in method to find the current rule, so there must be an internal operation.

[DllImport(<span class="cpp-string">"user32.dll"</span>, CharSet=CharSet.Ansi)]<span class="cs-keyword">private</span> <span class="cs-keyword">static</span> <span class="cs-keyword">extern</span> IntPtr SendMessage(IntPtr hWnd,                         <span class="cs-keyword">int</span> msg, <span class="cs-keyword">int</span> len, <span class="cs-keyword">ref</span> <span class="cs-keyword">int</span> [] order); <span class="cs-comment">// ListView messages</span><span class="cs-keyword">private</span> <span class="cs-keyword">const</span> <span class="cs-keyword">int</span> LVM_FIRST = <span class="cs-literal">0x1000</span>;<span class="cs-keyword">private</span> <span class="cs-keyword">const</span> <span class="cs-keyword">int</span> LVM_GETCOLUMNORDERARRAY = (LVM_FIRST + <span class="cs-literal">59</span>);

Using these declarations, you can useLVM_GETCOLUMNORDERARRAYMessage to getListView'S current column order.

By using the preceding statement, you can use lvm_getcolumnorderarray to obtain the sorting rules of the current listview column.

The next step is to move the editor control in place and to make it visible. once the actual editing is being stored med, the user must be able to accept or reject any changes he makes, so there are a few events that have to be caught while editing.

The next step is to move the editing control to a proper position and make it visible. once the actual editing operation is performed, the user must immediately accept or reject any operations by the user. Therefore, some events must be captured during editing.

Usually, a click outside the editor control accepts any changes made, as does the return key. Pressing ESC while in-place editing mode converts back to the originalSubItemText.

Generally, when you click the button outside the editing control to accept the operation, press the enter button, and then press the ESC button inside the control to return to the original text.

Because the editor control actually is not part ofListView, I also had to look for any action that might change the size or location of the editor control. This was done overridingWndProc:

Because the editing control is not part of the listview, I have to find any action to change the size and position of the editing control. It is implemented by overwriting wndproc:

<span class="cs-keyword">protected</span> <span class="cs-keyword">override</span> <span class="cs-keyword">void</span> WndProc(<span class="cs-keyword">ref</span> Message msg){    <span class="cs-keyword">switch</span> (msg.Msg)    {        <span class="cs-comment">// Look for WM_VSCROLL, WM_HSCROLL or WM_SIZE messages.</span>        <span class="cs-keyword">case</span> WM_VSCROLL:        <span class="cs-keyword">case</span> WM_HSCROLL:        <span class="cs-keyword">case</span> WM_SIZE:            EndEditing(<span class="cs-keyword">false</span>);            <span class="cs-keyword">break</span>;        <span class="cs-keyword">case</span> WM_NOTIFY:        <span class="cs-comment">// Look for WM_NOTIFY of events that might also change the</span>        <span class="cs-comment">// editor's position/size: Column reordering or resizing</span>        NMHDR h = (NMHDR)Marshal.PtrToStructure(msg.LParam, <span class="cs-keyword">typeof</span>(NMHDR));        <span class="cs-keyword">if</span> (h.code == HDN_BEGINDRAG ||            h.code == HDN_ITEMCHANGINGA ||            h.code == HDN_ITEMCHANGINGW)            EndEditing(<span class="cs-keyword">false</span>);        <span class="cs-keyword">break</span>;    }     <span class="cs-keyword">base</span>.WndProc(<span class="cs-keyword">ref</span> msg);}

Here, scrolling and resizing ofListViewAre monitored as well as changes toListView'S column headers. If one of these messages is wrongly Ed, the input focus is transferred back toListView, Thus ending in-place editing.

If one of the messages is received, the input focus is returned to listview to end the editing.

 

How to Use listviewex for in-place editing

There are two ways to perform in-place editingListViewEx. First, you can use the newSubItemClickedEvent togetherGetSubItemBounds()To position your editor control by yourself, or you can useStartEditing(), Which performs all required calculations and Control Positioning by itself.

You can use the new subitemclicked and getsubitembounds () to locate the new edit control. You can also use startediting () to execute all the calculations and control positioning.

So, usually you wocould start by addingListViewExAnd at least one control used as a cell editor to yourForm. Don't forget to make your cell editor control invisible! Then wire up an event handlerSubItemClickedAnd actually start editing:

Generally, you should first add a listviewex and use at least one control as a cell editor. Do not forget to make your cell editor invisible. Then bind an event handle to subitemclicked.

<span class="cs-keyword">private</span> <span class="cs-keyword">void</span> listViewEx1_SubItemClicked(<span class="cs-keyword">object</span> sender,                          ListViewEx.SubItemClickEventArgs e){    <span class="cs-comment">// Here, I use a ComboBox (comboBox1) as a cell editor:</span>    listViewEx1.StartEditing(comboBox1, e.Item, e.SubItem);}

That's it.

'I ve got ded a small sample application to show you how to useListViewExWith several different cell editors. Feel free to use the control or the source to your heart's desire and have fun!

Additional features

Your comments gave me some hints on missing features, so meanwhile I 've added an additional PropertyDoubleClickActivationSo that you can decide if the listviewex shocould enter editing mode when you click on a subitem or if a double click is required.

Another point was adding two new events (SubItemBeginEditingAndSubItemEndEditing) To give the caller the possibility to control what's displayed in the editing control and what gets put back intoListViewSubItem.
Now you're able to add a password field as a cell editor and transfer the plain password to and from the edit control without having it shown in the listview. take a look at the sample project to see how it's done.

 

Translation is too annoying. Check the source code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.