使用ComboBox控件对ListView控件中的数据进行编辑

原创 2007年09月19日 21:27:00
by jingzhongrong
在默认状态下,ListView控件的编辑功能是通过提供一个类似Edit控件的栏来实现的。但是如果你想让界面更加友好或者希望使用其他类型的控件来编辑数据,以提高操作的便利性。如下图所示,我们利用一个ComboBox控件来让用户以选择的方式来编辑数据。
(图片)
在上述图片中,使用ComboBox控件进行选择,选中的项目可以直接对ListView中的“插件状态”栏进行修改。其中还涉及对ComboBox控件和ListView控件的自绘,不属于此文所要描述的范围,略过这部分的代码以及实现。如果需要了解有关控件自绘的信息,可以自行到网上搜索。此文的编译环境是C++Builder 2007。
下面具体说明实现的方法。首先添加ListView控件以及ComboBox控件到程序中,并设置ComboBox控件的Visible属性默认为false。
1、每当用户单击ListView控件时,我们应该获取鼠标此时单击的位置,并根据位置计算出所在行以及所在的列(如上图,ComboBox出现在第二列中,只有当鼠标单击的位置在ListView第二列中才会出现ComboBox让用户进行选择)。
判断用户单击的行及列使用如下代码:
//在ListView控件的OnMouseUp事件中添加如下代码
TListView *listview = (TListView*)Sender;
TListItem *lv = listview->GetItemAt(X,Y);
if(lv)   //如果选中一项
{
    TPoint p(X,Y);
    TRect ClickedItem = lv->DisplayRect(drBounds);    //获取选择的项目的边框
    TRect rct(ClickedItem);
      int CellLeft = rct.Left, CellIndex = 0;     //下面计算鼠标单击的位置处在哪一列中
    for(int x = 0; x < listview->Columns->Count; x++)
    {
      rct.Left = CellLeft;
      rct.Right = CellLeft + listview->Column[x]->Width;
      if(PtInRect(rct,p))       //鼠标单击位置在x+1列中
      {
        CellIndex = x + 1;
        break;
      }
      CellLeft += listview->Column[x]->Width;
    }
    //检查鼠标点击位置是否位于"插件状态"一列中(对应上图实现)
    if(CellIndex != 2)
             return;
         else   //处于“插件状态”列中
         {
                  …   //暂时省略此处代码
         }
}
2、此时我们已经判断得出鼠标单击的位置是否应该显示出ComboBox控件。下面我们继续进行判断,此时我们应该考虑到这个列可能处于完全不可见的状态或者部分可见的状态,我们应该调整ComboBox的位置以及大小之后才能显示出来。
上述步骤中变量ClickedItem便是用于保存ComboBox应该的大小以及位置。我们根据下面的代码对ClickedItem进行修正。
//检查数据行是否已经完全滚动至左侧之外
if((ClickedItem.Left + listview->Column[0]->Width + listview->Column[1]->Width) < 0)
    return;   //单元格在左侧之外无法看到不做处理
//
//检查数据行是否部分被滚动至左侧之外
//By jingzhongrong
else if(ClickedItem.Left + listview->Column[0]->Width < 0)
{
    //检查此数据行是否已延伸至ListView的右侧之外
    if((ClickedItem.Left + listview->Column[1]->Width + listview->Column[0]->Width) > listview->Width)
    {
        //将数据行(ComboBox)的宽度设置成ListView的宽度
        ClickedItem.Left = 0;
        ClickedItem.Right = ClickedItem.Left + listview->Width;
    }
    else
    {
           //单元格的右侧位于视图之中
        ClickedItem.Right = ClickedItem.Left + listview->Column[0]->Width + listview->Column[1]->Width;
        ClickedItem.Left = 0;
    }
}
//检查数据行是否已经完全滚动至右侧之外
else if(ClickedItem.Left + listview->Column[0]->Width > listview->Width)
    return;      //单元格在右侧之外无法看到不做处理
//数据行被部分滚动至右侧之外
else if(listview->Column[1]->Width + listview->Column[0]->Width > listview->Width)
{
    ClickedItem.Left += listview->Column[0]->Width;
ClickedItem.Right = listview->Width - ClickedItem.Left;
}
else
{
    ClickedItem.Left = listview->Column[0]->Width;
    ClickedItem.Right = listview->Column[1]->Width;
}
//进行调整
ClickedItem.Left += listview->Left;
ClickedItem.Top += 25;       //Columns Height
ClickedItem.Right += ClickedItem.Left;
3、此时的ClickedItem已经保存ComboBox应该出现的位置,我们下面显示出ComboBox来。
this->ComboBox1->Top = ClickedItem.Top;
this->ComboBox1->Left = ClickedItem.Left;
this->ComboBox1->Width = ClickedItem.Width();
//对ComboBox显示的文本进行设置
//ComboBox应在初始化时添加选择项并将其Style属性设置为csDropDownList用来限制
//用户的选择
if(lv->SubItems->Strings[0] == "启用")
    this->ComboBox1->ItemIndex = 0;
else
this->ComboBox1->ItemIndex = 1;
//By jingzhongrong
this->ComboBox1->Visible = true;
this->ComboBox1->BringToFront();
this->ComboBox1->SetFocus();
4、至此,我们已经将ComboBox控件显示出来。下面我们处理ComboBox进行选择。在ComboBox控件的OnChange事件中添加如下代码。
AnsiString str = this->ListView1->Selected->SubItems->Strings[0];
this->ListView1->Selected->SubItems->Strings[0] = ComboBox1->Text;
ComboBox1->Visible = false;
//判断ComboBox选择前后是否有更改过
if(str != ComboBox1->Text && ComboBox1->Text == "启用")
{
 this->LoadPlugin(…);      //加载插件
}
else if(str != ComboBox1->Text && ComboBox1->Text == "禁用")
{
 this->LoadPlugin(…);      //卸载插件
}
5、继续处理ComboBox控件,在OnExit事件中添加代码,隐藏ComboBox控件。
AnsiString str = this->ListView1->Selected->SubItems->Strings[0];
if(str == "")
{
    ComboBox1->Visible = false;
}
else
{
    this->ListView1->Selected->SubItems->Strings[0] = ComboBox1->Text;
    ComboBox1->Visible = false;
    if(str != ComboBox1->Text && ComboBox1->Text == "启用")
    {
      this->LoadPlugin();      //load
    }
    else if(str != ComboBox1->Text && ComboBox1->Text == "禁用")
    {
      this->LoadPlugin();      //unload
}
}
this->ListView1->SetFocus();
6、OnKeyPress事件对Esc键以及Enter键进行处理
switch(Key)
{
    case VK_ESCAPE:
      //其他处理,此处省略
      //…
      this->ComboBox1->Visible = false;
      this->ListView1->SetFocus();
      break;
    case VK_RETURN:
      this->ComboBox1->Visible = false;
      this->ListView1->SetFocus();
      break;
}
7、在最后,我们应该对WM_VSCROLL和WM_HSCROLL两个消息进行处理。这两个消息会在用户垂直或者水平滚动ListView控件时引发。因为我们的ComboBox实际上并非ListView控件的一部分,因此,ComboBox控件并不会随着ListView控件的滚动而滚动。所以我们在这两个消息引发时将ComboBox控件隐藏起来。我们可以有几种方法来实现。可以继承TListView控件,然后对WndProc进行重载,然后在WndProc函数中过滤掉这两个消息。
下面我采用的是另外一种方法,需要在窗体OnCreate事件中加入以下代码:
 OldListViewWindowProc = ListView1->WindowProc;
 ListView1->WindowProc = MyListViewWindowProc;
相应的在头文件中增加以下代码:
 TWndMethod OldListViewWindowProc;
 void __fastcall MyListViewWindowProc(TMessage &Message);
下面是MyListViewWindowProc函数的实现
if(Message.Msg == WM_VSCROLL || Message.Msg == WM_HSCROLL)
{
    ListView1->SetFocus();
}
OldListViewWindowProc(Message);    //调用默认的处理函数处理其他消息
通过上述步骤,可以基本上可以实现使用ComboBox控件对ListView控件的项进行编辑。
By jingzhongrong 2007-9-19
 

使用telerik combobox控件显示数据

效果: 逻辑代码 protected void Page_Load(object sender, EventArgs e) { FillRadCBDep...

【转】c#中ListView控件加入ComboBox

转自:http://www.shangxueba.com/jingyan/95154.html 很多项目中要用到ListView控件来呈现并编辑数据。为方便用户的输入,可在ListView控件中...

ComboBox控件绑定数据源

最近在研究机房收费系统的组合查询的方法时,看到了ComboBox控件可以进行数据绑定,我觉得这个功能真的很不错,可以给我省去很多的麻烦。 一、数据转换方法 现在我们开看一下我以前写的一段代码: 1、界...

ComboBox控件的数据绑定

ComboBox控件是一个下拉组合控件,该控件可以让用户输入或下拉选择内容。在使用的时候经常只是绑定数据表中的其中一列或把其中一列的值添加到Items中,如:name 。但在查询或使用的时候有可能需...
  • tdtxflsh
  • tdtxflsh
  • 2011年03月09日 13:14
  • 22766

Combobox 控件绑定数据

ComboBox 类:表示带有下拉列表的选择控件,通过单击控件上的箭头可显示或隐藏下拉列表。...

winform快速开发平台之代码抽象->快速绑定ComboBox数据控件

通常我们在处理编辑窗体时。往往会遇到数据绑定。例如combobox控件绑定数据字典可能是我们经常用到的。然而在我的winform快速开发平台中我是如何处理这个频繁的操作呢? 首先,我们要绑定co...

WinForm 中 comboBox控件之数据绑定

http://www.cnblogs.com/peterzb/archive/2009/05/30/1491923.html            下面介绍三种对comboBox绑定的方式,分别是泛...
  • farcall
  • farcall
  • 2014年12月30日 19:06
  • 654

ComboBox控件的数据绑定

ComboBox控件是一个下拉组合控件,该控件可以让用户输入或下拉选择内容。在使用的时候经常只是绑定数据表中的其中一列或把其中一列的值添加到Items中,如:name 。但在查询或使用的时候有可能需要...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用ComboBox控件对ListView控件中的数据进行编辑
举报原因:
原因补充:

(最多只允许输入30个字)