当前位置:   article > 正文

改造winform的listview实现双击修改数据editbox和下拉框选择数据combobox功能_c# listview 双击编辑

c# listview 双击编辑

一直以来winform的listview都只是作为数据输出显示来用, 想要实现数据的双向操作比较难

之前都需要用其他表格类控件实现这个双击编辑文本,双击实现下拉列表框选择文本功能, 而且其中有很大一部分是ocx组件, 

那么就需要在客户电脑上regsvr32 注册它, 这样就需要管理员权限, 这样操作并不是很好, 

于是考虑着手动改造listview使其满足我的需求.

还好, aardio范例里有个数据视图win.ui.grid的库可供参考, 我就是根据这个库内的实现方法来升级改造的.

下面我在原listview grid基础上增加了, 双击指定列 可直接编辑文本  / 弹出下拉框选择文本 功能.

 listviewEX.aardio 库代码如下:

  1. //listview 扩展
  2. import win.ui.ctrl.edit;
  3. import win.ui.ctrl.combobox;
  4. namespace win.ui;
  5. class listviewEx{
  6. ctor( listview ){
  7. this = listview;
  8. this.fullRow = 1;
  9. this.gridLines = 1;
  10. this.columnsEditbox = {};//记录编辑框列号
  11. this.columnsCombobox = {};//记录下拉框列号和列表值
  12. //添加下拉框模板
  13. this.addCtrl(
  14. combobox = {
  15. cls="combobox";font = LOGFONT( h = -19 );left = 0;top = 0;
  16. right = 50;bottom = 50;autoResize = false ;hide = 1;edge = 1;mode="dropdownlist";
  17. wndproc = function( hwnd, message, wParam, lParam ){
  18. var update;
  19. var event = owner.event;
  20. if( message == 308 ) {
  21. update = true;
  22. }
  23. if( update ){
  24. owner.show(false);
  25. var t = this.getItemText(event.iItem,event.iSubItem );
  26. if( t!= owner.text ){
  27. if( this.onEditChanged ) {
  28. if( false === this.onEditChanged(owner.text, event.iItem, event.iSubItem))
  29. return;
  30. }
  31. this.setItemText( owner.text, event.iItem, event.iSubItem );
  32. }
  33. if(this.onEditEnd){
  34. this.onEditEnd(event.iItem, event.iSubItem);
  35. }
  36. }
  37. }
  38. }
  39. );
  40. //添加编辑框模板
  41. this.addCtrl(
  42. editBox = {
  43. cls="edit";font = LOGFONT( h = -19 );left = 0;top = 0;
  44. right = 50;bottom = 50;autoResize = false ;hide = 1;edge = 1;
  45. wndproc = function( hwnd, message, wParam, lParam ){
  46. var update;
  47. var event = owner.event;
  48. if( ( message = 0x8/*_WM_KILLFOCUS*/) || (message == 0x101/*_WM_KEYUP*/ && wParam == 0xD/*_VK_RETURN*/ ) ) {
  49. update = true;
  50. }
  51. elseif(message == 0x201/*_WM_LBUTTONDOWN*/ ){
  52. var x,y = ..win.getMessagePos(lParam)
  53. var rc = this.editBox.getClientRect();
  54. if( ! ::PtInRect(rc,x,y) ) update = true;
  55. this.editBox.capture = !update;
  56. }
  57. elseif(message == 0x101/*_WM_KEYUP*/){
  58. if( wParam == 0xD/*_VK_RETURN*/ ) update = true;
  59. elseif( wParam == 0x1B/*_VK_ESC*/){
  60. owner.text = this.getItemText(event.iItem,event.iSubItem );
  61. update = true;
  62. }
  63. }
  64. if( update ){
  65. owner.show(false);
  66. var t = this.getItemText(event.iItem,event.iSubItem );
  67. if( t!= owner.text ){
  68. if( this.onEditChanged ) {
  69. if( false === this.onEditChanged(owner.text, event.iItem, event.iSubItem))
  70. return;
  71. }
  72. this.setItemText( owner.text, event.iItem, event.iSubItem );
  73. }
  74. if(this.onEditEnd){
  75. this.onEditEnd(event.iItem, event.iSubItem);
  76. }
  77. }
  78. }
  79. }
  80. )
  81. };
  82. //绘制下拉框
  83. beginCombobox = function(iItem,iSubItem){
  84. var combobox = this.combobox;
  85. if( ..win.isVisible(combobox.hwnd) ) return;
  86. var event = this.combobox.event;
  87. if(iItem===null && iSubItem===null) {
  88. iItem = event.iItem;
  89. iSubItem = event.iSubItem;
  90. }
  91. else {
  92. event = {
  93. iItem = iItem;
  94. iSubItem = iSubItem;
  95. };
  96. combobox.event = event;
  97. }
  98. combobox.items = this.columnsCombobox[iSubItem];
  99. combobox.selText=this.getItemText(iItem,iSubItem);
  100. var rc=this.getItemRect(iItem,iSubItem,,2/*_LVIR_LABEL*/ );
  101. rc.inflate(2,2);
  102. combobox.setRect(rc);
  103. combobox.showDropDown();
  104. return true;
  105. };
  106. //绘制编辑框
  107. beginEdit = function(iItem,iSubItem){
  108. var edit = this.editBox;
  109. if( ..win.isVisible(edit.hwnd) ) return;
  110. var event = this.editBox.event;
  111. if(iItem===null && iSubItem===null) {
  112. iItem = event.iItem;
  113. iSubItem = event.iSubItem;
  114. }
  115. else {
  116. event = {
  117. iItem = iItem;
  118. iSubItem = iSubItem;
  119. };
  120. edit.event = event;
  121. }
  122. edit.text=this.getItemText(iItem,iSubItem);
  123. var rc=this.getItemRect(iItem,iSubItem,,2/*_LVIR_LABEL*/ );
  124. rc.inflate(2,2);
  125. edit.setRect(rc);
  126. edit.show();
  127. edit.setFocus();
  128. edit.capture = true;
  129. return true;
  130. };
  131. //设置下拉框模式 列号/下拉值
  132. setcolumnsCombobox = function(iSubItem,tab,...){
  133. var c = type(tab) === "table" ? tab : {tab,...}
  134. this.columnsCombobox[iSubItem] = c;
  135. };
  136. //设置编辑框模式 列号
  137. setcolumnsEditbox = function(...){
  138. var c = type(...) === "table" ? ... : {...}
  139. for(i,idx in c) this.columnsEditbox[idx] = 1;
  140. };
  141. prenotify = {
  142. [0xFFFFFFFD/*_NM_DBLCLK*/] = function(id,code,ptr){
  143. var event = this.getNotifyMessage(code,ptr);
  144. if( ! event.iItem && event.iSubItem ) return ;
  145. //启用 编辑框
  146. if( this.columnsEditbox[event.iSubItem] ){
  147. this.editBox.event = event;
  148. this.beginEdit();
  149. };
  150. //启用 下拉框
  151. if( this.columnsCombobox[event.iSubItem] ){
  152. this.combobox.event = event;
  153. this.beginCombobox();
  154. };
  155. };
  156. }
  157. }
  158. /**intellisense()
  159. win.ui.listviewEx(__) = 参数必须指定一个listview控件对象\n返回一个可编辑单元格的列表视图对象,\n\n鼠标左键单击单元格、或者按空格键开始编辑,\n回车完成编辑,ESC键撤消编辑,回车+上下方向键快速移动到其他项,\n用户完成编辑后会触发onEditChanged事件.\n!listview.
  160. win.ui.listviewEx() = !win_ui_listviewEx.
  161. !win_ui_listviewEx.edit = 实现编辑功能的edit控件\n此功能需要扩展listview并实现了编辑功能的的控件才能支持\n!edit.
  162. !win_ui_listviewEx.combobox = 实现编辑功能的edit控件\n此功能需要扩展listview并实现了编辑功能的的控件才能支持\n!combobox.
  163. !win_ui_listviewEx.onEditChanged(text,iItem,iSubItem) = @.onEditChanged = function(text,iItem,iSubItem){
  164. __/*控件完成编辑,并且文本已变更,\ntext为改变后的文本,iItem为行号,iSubItem为列号\n此功能需要扩展listview并实现了编辑功能的的控件才能支持\n返回false可中止更新显示文本*/
  165. }
  166. !win_ui_listviewEx.onEditEnd(iItem,iSubItem) = @.onEditEnd = function(iItem,iSubItem){
  167. __/*控件完成编辑*/
  168. }
  169. !win_ui_listviewEx.setTable(__) = 用listview控件显示数据表\n此函数会自动清空控件之前的所有项,\n如果没有创建任何列,则自动创建列\n\n数据表应当包含行组成的数组,\n每行的数据列必须是由列名和列值组成的键值对\n数据表应使用fields包含需要显示的列名称数组\n可以通过fields控制要显的列、以及要显示的顺序\n\n使用sqlite,access,sqlServer等数据库对象提供的getTable函数可获取符合此规格的数据表
  170. !win_ui_listviewEx.setColumns(__) = 用一个字符串数组指定要显示的列\n如果参数为空则清空所有列
  171. !win_ui_listviewEx.setcolumnsCombobox(__) = 可以使用一个或多个参数指定要禁止编辑的列序号,\n也可以用一个数组参数指定多个列序号
  172. !win_ui_listviewEx.setcolumnsEditbox(__) = 可以使用一个或多个参数指定要编辑的列序号,\n也可以用一个数组参数指定多个列序号
  173. !win_ui_listviewEx.clear() = 清空所有行
  174. !win_ui_listviewEx.clear(true) = 清空所有行,并且清空所有列
  175. end intellisense**/

使用也很简单, 只需要指定哪一列是文本框模式, 哪一列是下拉框模式.

  1. import win.ui;
  2. /*DSG{{*/
  3. mainForm = win.form(text="testListviewEx";right=740;bottom=315;bgcolor=16777215)
  4. mainForm.add(
  5. 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}
  6. )
  7. /*}}*/
  8. import console
  9. console.open()
  10. import win.ui.listviewEx;
  11. var grid = win.ui.listviewEx(mainForm.listview);
  12. grid.setcolumnsEditbox(2);
  13. grid.setcolumnsCombobox(3,"10","1000","2000","5000");
  14. grid.setcolumnsCombobox(4,{"Z+","Z-","ZNP+","ZNP-"});
  15. grid.setcolumnsCombobox(5,{"急停","减速停"});
  16. grid.onEditChanged = function(text,iItem,iSubItem){
  17. console.log("onEditChanged",text,iItem,iSubItem)
  18. }
  19. import win.imageList;
  20. var iml = win.imageList(1,30);
  21. mainForm.listview.setImageList( iml,1/*_LVSIL_NORMAL*/ );
  22. mainForm.listview.setColumns(
  23. {"轴号","加减速时间","单脉冲运动量","找零方式","停止方式"},
  24. {60,120,120,100,100},
  25. {2,2,2,2,2},
  26. );
  27. var axisData = {};
  28. for(i=1;20;1){
  29. axisData[i]={};
  30. axisData[i][1] = "轴"++i;
  31. axisData[i][2] = "0.1";
  32. axisData[i][3] = "1";
  33. axisData[i][4] = "Z+";
  34. axisData[i][5] = "急停";
  35. }
  36. mainForm.listview.items = axisData;
  37. mainForm.show();
  38. return win.loopMessage();

主要看上面部分, 上面声明完所有的列功能, 下面还是用listview自己的功能实现代码.

完整示例工程可以去我的博客下载:

 改造listview使其实现表格内编辑框editbox和下拉列表框combobox功能 - 上位机开发笔记一直以来winform的listview都只是作为数据输出显示来用, 想要实现数据的双向操作比较难之前都需要用其他表格类控件实现这个双击编辑文本,双击实现下拉列表框选择文本功能, 而且其中有很大一部分是ocx组件, 那么就需要在客户电脑上regsvr32 注册它, 这样就需要管理员权限, 这样操作并https://aardio.com.cn/t/21395

另外, 如果有更新会在我的博客第一时间更新, 有代码方面的问题也可以去那里跟帖提问.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/537716
推荐阅读
相关标签
  

闽ICP备14008679号