一直以来winform的listview都只是作为数据输出显示来用,想要实现数据的双向操作比较难之前都需要用其他表格类控件实现这个双击编辑文本,双击实现下拉列表框选择文本功能,而且其中有很大一部分
一直以来winform的listview都只是作为数据输出显示来用, 想要实现数据的双向操作比较难
之前都需要用其他表格类控件实现这个双击编辑文本,双击实现下拉列表框选择文本功能, 而且其中有很大一部分是ocx组件,
那么就需要在客户电脑上regsvr32 注册它, 这样就需要管理员权限, 这样操作并不是很好,
于是考虑着手动改造listview使其满足我的需求.
还好, aardio范例里有个数据视图win.ui.grid的库可供参考, 我就是根据这个库内的实现方法来升级改造的.
下面我在原listview grid基础上增加了, 双击指定列 可直接编辑文本 / 弹出下拉框选择文本 功能.
listviewEX.aardio 库代码如下:
//listview 扩展import win.ui.ctrl.edit;import win.ui.ctrl.combobox;namespace win.ui;class listviewEx{ ctor( listview ){ this = listview; this.fullRow = 1; this.gridLines = 1; this.columnsEditbox = {};//记录编辑框列号 this.columnsCombobox = {};//记录下拉框列号和列表值 //添加下拉框模板 this.addCtrl( combobox = { cls=\"combobox\";font = LOGFONT( h = -19 );left = 0;top = 0; right = 50;bottom = 50;autoResize = false ;hide = 1;edge = 1;mode=\"dropdownlist\"; wndproc = function( hwnd, message, wParam, lParam ){ var update; var event = owner.event; if( message == 308 ) { update = true; } if( update ){ owner.show(false); var t = this.getItemText(event.iItem,event.iSubItem ); if( t!= owner.text ){ if( this.onEditChanged ) { if( false === this.onEditChanged(owner.text, event.iItem, event.iSubItem)) return; } this.setItemText( owner.text, event.iItem, event.iSubItem ); } if(this.onEditEnd){ this.onEditEnd(event.iItem, event.iSubItem); } } } } ); //添加编辑框模板 this.addCtrl( editBox = { cls=\"edit\";font = LOGFONT( h = -19 );left = 0;top = 0; right = 50;bottom = 50;autoResize = false ;hide = 1;edge = 1; wndproc = function( hwnd, message, wParam, lParam ){ var update; var event = owner.event; if( ( message = 0x8/*_WM_KILLFOCUS*/) || (message == 0x101/*_WM_KEYUP*/ && wParam == 0xD/*_VK_RETURN*/ ) ) { update = true; } elseif(message == 0x201/*_WM_LBUTTONDOWN*/ ){ var x,y = ..win.getMessagePos(lParam) var rc = this.editBox.getClientRect(); if( ! ::PtInRect(rc,x,y) ) update = true; this.editBox.capture = !update; } elseif(message == 0x101/*_WM_KEYUP*/){ if( wParam == 0xD/*_VK_RETURN*/ ) update = true; elseif( wParam == 0x1B/*_VK_ESC*/){ owner.text = this.getItemText(event.iItem,event.iSubItem ); update = true; } } if( update ){ owner.show(false); var t = this.getItemText(event.iItem,event.iSubItem ); if( t!= owner.text ){ if( this.onEditChanged ) { if( false === this.onEditChanged(owner.text, event.iItem, event.iSubItem)) return; } this.setItemText( owner.text, event.iItem, event.iSubItem ); } if(this.onEditEnd){ this.onEditEnd(event.iItem, event.iSubItem); } } } } ) }; //绘制下拉框 beginCombobox = function(iItem,iSubItem){ var combobox = this.combobox; if( ..win.isVisible(combobox.hwnd) ) return; var event = this.combobox.event; if(iItem===null && iSubItem===null) { iItem = event.iItem; iSubItem = event.iSubItem; } else { event = { iItem = iItem; iSubItem = iSubItem; }; combobox.event = event; } combobox.items = this.columnsCombobox[iSubItem]; combobox.selText=this.getItemText(iItem,iSubItem); var rc=this.getItemRect(iItem,iSubItem,,2/*_LVIR_LABEL*/ ); rc.inflate(2,2); combobox.setRect(rc); combobox.showDropDown(); return true; }; //绘制编辑框 beginEdit = function(iItem,iSubItem){ var edit = this.editBox; if( ..win.isVisible(edit.hwnd) ) return; var event = this.editBox.event; if(iItem===null && iSubItem===null) { iItem = event.iItem; iSubItem = event.iSubItem; } else { event = { iItem = iItem; iSubItem = iSubItem; }; edit.event = event; } edit.text=this.getItemText(iItem,iSubItem); var rc=this.getItemRect(iItem,iSubItem,,2/*_LVIR_LABEL*/ ); rc.inflate(2,2); edit.setRect(rc); edit.show(); edit.setFocus(); edit.capture = true; return true; }; //设置下拉框模式 列号/下拉值 setcolumnsCombobox = function(iSubItem,tab,...){ var c = type(tab) === \"table\" ? tab : {tab,...} this.columnsCombobox[iSubItem] = c; }; //设置编辑框模式 列号 setcolumnsEditbox = function(...){ var c = type(...) === \"table\" ? ... : {...} for(i,idx in c) this.columnsEditbox[idx] = 1; }; prenotify = { [0xFFFFFFFD/*_NM_DBLCLK*/] = function(id,code,ptr){ var event = this.getNotifyMessage(code,ptr); if( ! event.iItem && event.iSubItem ) return ; //启用 编辑框 if( this.columnsEditbox[event.iSubItem] ){ this.editBox.event = event; this.beginEdit(); }; //启用 下拉框 if( this.columnsCombobox[event.iSubItem] ){ this.combobox.event = event; this.beginCombobox(); }; }; } }/**intellisense()win.ui.listviewEx(__) = 参数必须指定一个listview控件对象\\n返回一个可编辑单元格的列表视图对象,\\n\\n鼠标左键单击单元格、或者按空格键开始编辑,\\n回车完成编辑,ESC键撤消编辑,回车+上下方向键快速移动到其他项,\\n用户完成编辑后会触发onEditChanged事件.\\n!listview.win.ui.listviewEx() = !win_ui_listviewEx.!win_ui_listviewEx.edit = 实现编辑功能的edit控件\\n此功能需要扩展listview并实现了编辑功能的的控件才能支持\\n!edit.!win_ui_listviewEx.combobox = 实现编辑功能的edit控件\\n此功能需要扩展listview并实现了编辑功能的的控件才能支持\\n!combobox.!win_ui_listviewEx.onEditChanged(text,iItem,iSubItem) = @.onEditChanged = function(text,iItem,iSubItem){ __/*控件完成编辑,并且文本已变更,\\ntext为改变后的文本,iItem为行号,iSubItem为列号\\n此功能需要扩展listview并实现了编辑功能的的控件才能支持\\n返回false可中止更新显示文本*/}!win_ui_listviewEx.onEditEnd(iItem,iSubItem) = @.onEditEnd = function(iItem,iSubItem){ __/*控件完成编辑*/}!win_ui_listviewEx.setTable(__) = 用listview控件显示数据表\\n此函数会自动清空控件之前的所有项,\\n如果没有创建任何列,则自动创建列\\n\\n数据表应当包含行组成的数组,\\n每行的数据列必须是由列名和列值组成的键值对\\n数据表应使用fields包含需要显示的列名称数组\\n可以通过fields控制要显的列、以及要显示的顺序\\n\\n使用sqlite,access,sqlServer等数据库对象提供的getTable函数可获取符合此规格的数据表 !win_ui_listviewEx.setColumns(__) = 用一个字符串数组指定要显示的列\\n如果参数为空则清空所有列!win_ui_listviewEx.setcolumnsCombobox(__) = 可以使用一个或多个参数指定要禁止编辑的列序号,\\n也可以用一个数组参数指定多个列序号!win_ui_listviewEx.setcolumnsEditbox(__) = 可以使用一个或多个参数指定要编辑的列序号,\\n也可以用一个数组参数指定多个列序号!win_ui_listviewEx.clear() = 清空所有行!win_ui_listviewEx.clear(true) = 清空所有行,并且清空所有列end intellisense**/
使用的时候也很简单, 直接指定哪一列是需要文本编辑, 哪一列需要下拉框编辑即可.还可以指定下拉框内容哦
import win.ui;/*DSG{{*/mainForm = win.form(text=\"testListviewEx\";right=740;bottom=315;bgcolor=16777215)mainForm.add(listview={cls=\"listview\";left=13;top=8;right=729;bottom=309;border=1;db=1;dl=1;dr=1;dt=1;font=LOGFONT(h=-13);fullRow=1;gridLines=1;msel=false;vscroll=1;z=1})/*}}*/import consoleconsole.open()import win.ui.listviewEx;var grid = win.ui.listviewEx(mainForm.listview);grid.setcolumnsEditbox(2);grid.setcolumnsCombobox(3,\"10\",\"1000\",\"2000\",\"5000\");grid.setcolumnsCombobox(4,{\"Z+\",\"Z-\",\"ZNP+\",\"ZNP-\"});grid.setcolumnsCombobox(5,{\"急停\",\"减速停\"});grid.onEditChanged = function(text,iItem,iSubItem){ console.log(\"onEditChanged\",text,iItem,iSubItem)}import win.imageList;var iml = win.imageList(1,30);mainForm.listview.setImageList( iml,1/*_LVSIL_NORMAL*/ );mainForm.listview.setColumns( {\"轴号\",\"加减速时间\",\"单脉冲运动量\",\"找零方式\",\"停止方式\"}, {60,120,120,100,100}, {2,2,2,2,2},);var axisData = {};for(i=1;20;1){ axisData[ i ]={}; axisData[ i ][1] = \"轴\"++i; axisData[ i ][2] = \"0.1\"; axisData[ i ][3] = \"1\"; axisData[ i ][4] = \"Z+\"; axisData[ i ][5] = \"急停\";}mainForm.listview.items = axisData;mainForm.show();return win.loopMessage();
本文内容由互联网用户自发贡献,该文观点仅代表作者本人,本站仅供展示。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 97552693@qq.com 举报,一经查实,本站将立刻删除。