一直以来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 console
console.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();
主要看上面部分, 上面声明完所有的列功能, 下面还是用listview自己的功能实现代码.
完整示例工程可以去我的博客下载:
改造listview使其实现表格内编辑框editbox和下拉列表框combobox功能 - 上位机开发笔记一直以来winform的listview都只是作为数据输出显示来用, 想要实现数据的双向操作比较难之前都需要用其他表格类控件实现这个双击编辑文本,双击实现下拉列表框选择文本功能, 而且其中有很大一部分是ocx组件, 那么就需要在客户电脑上regsvr32 注册它, 这样就需要管理员权限, 这样操作并https://aardio.com.cn/t/21395文章来源:https://www.toymoban.com/news/detail-455511.html
另外, 如果有更新会在我的博客第一时间更新, 有代码方面的问题也可以去那里跟帖提问.文章来源地址https://www.toymoban.com/news/detail-455511.html
到了这里,关于改造winform的listview实现双击修改数据editbox和下拉框选择数据combobox功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!