实现 Combobox 显示内容与值不同

使用Combobox提供的AddItem的方法:

procedure AddItem(Item: String; AObject: TObject);
Item:添加项的字符串值。
AObject:关联的对象。

AddItem 方法添加项目同时与AObject对象进行关联,并可以读取、修改被关联对象。
就实现了显示内容与值的不同了。

******************************************************************************************************

{以下为基础测试代码,具体防空值等自行处理}
type
  TComboBoxObject = class(TObject)
  private
    ID: Integer;
    ShowStr: String;
    Other: String;
  end;

//添加数据
procedure TForm1.Button1Click(Sender: TObject);
var
  temp: TComboBoxObject;
begin
  temp:= TComboBoxObject.Create;
  temp.ID:= StrToInt(Edit1.Text);
  temp.ShowStr:= Edit2.Text;
  temp.Other:= Edit3.Text;
  ComboBox1.Items.AddObject(temp.ShowStr,temp);
end;

//选中时获取数据
procedure TForm1.ComboBox1Select(Sender: TObject);
begin
  Edit4.Text:= StrToInt((ComboBox1.Items.Objects[ComboBox1.ItemIndex] as TComboBoxObject).ID);
  Memo1.Lines.Add(ComboBox1.Text);
  Memo2.Lines.Add((ComboBox1.Items.Objects[ComboBox1.ItemIndex] as TComboBoxObject).Other);
end;

//删除选中项
procedure TForm1.Button2Click(Sender: TObject);
begin
  ComboBox1.Items.Objects[ComboBox1.ItemIndex].Free;
  ComboBox1.Items.Delete(ComboBox1.ItemIndex);
end;

//清空
procedure TForm1.Button3Click(Sender: TObject);
var 
  i :Integer;
begin 
  for i:=0 to ComboBox1.Items.Count-1 do
      ComboBox1.Items.Objects[i].Free;
  ComboBox1.Clear;
end;

******************************************************************************************************

网查资料:

TListBox组件的那个AddObject函数,用于保存一个数字很方便,因为Object参数本来就是一个指针,说白了本来就是数字,所以AddObject('字符',TObject(12)),以后,需要取出数字直接Integer(Objects[...])即可,不必去释放所谓的Object对象,因为根本没对象创建。但是我要保存一个record记录就麻烦了,所以考录到了TObject对象,下面是一些方法:

(1)、保存record的指针,发现record不做全局变量会丢失数据
type
   TRecord=record
     a,b:Integer;
   end;  
     var t:TRecord;
   begin
     t.a :=100;
     t.b :=100;
     ListBox1.Items.AddObject('测试',TObject(@t));//<--此处无法保存数据,因为变量t的指针是临时的。

(2)、使用TObject对象
type
   TMyObject=class(TObject)
   public
      a,b:Integer;
   end;

......
   var obj:TMyObject;
  begin
     obj :=TMyObject.Create;
     obj.a :=100;
     obj.b :=100;
     ListBox1.Items.AddObject('测试',obj);
  end;

数据是保存了,但是突然纠结起来了,TMyObject对象需要释放吗?就好像TRecord记录是否需要释放一样模糊起来了,大家看Delphi的TObject的源代码,几乎没有一处做了任何实质性的工作,Create是空的,Destory是空的,那么TObject对象需要释放吗?

 
分享到:


------解决方案--------------------
TMyObj是要释放的
你的方法1中,可以定义一个结构指针,然后New
type
   PRecord=^TRecord;
   TRecord=record
     a,b:Integer;
   end;  

     var t:PRecord;
   begin
     new(t);
     t.a :=100;
     t.b :=100;
     ListBox1.Items.AddObject('测试',TObject(@t));
不过,相应的,这个也要释放,需要dispose(xxxx);
------解决方案--------------------
Tobject的构造函数和析构函数为什么定义中为何没有代码,有两方面原因:

1:
详见《inside vcl 深入VCL架构剖析》第二章的2-6节,具体在79页

2:
详见《inside vcl 深入VCL架构剖析》中的第三章的3-2节,具体在“place holder方法”段。

delphi的对象的实例都是在堆中申请内存创建的,堆中的对象的生命周期跟全局变量的生命周期一样,都是跟程序的生命周期一致的。只有在栈中申请的内存才会随清栈工作时自动回收。
重申,create的对象一定要free,free的工作可以自己做也可以委托其他对象做,但必须明确自定确实做了free。
------解决方案--------------------
record 非TOBJECT,跟integer、single这些同属值类型。
而且似乎你有点混淆
var
 pInt: ^integer
  int: integer;
begin
  int:= 100; // int 是值类型的100
  getmem(pInt,4); // pInt 是指针,在堆中分配了4字节内存
  freemem(pInt); // pInt需要手动释放,而int不需要,它在栈中创建,函数结束就自动清栈一并销毁
end;
 
------解决方案--------------------
手动创建,手动释放。这是大多数编程的准则。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现ComboBox按钮在下拉时只显示指定字符串内容,可以通过以下步骤实现: 1. 在MFC窗口类的OnInitDialog()函数中,添加ComboBox控件,并设置ComboBox的样式为CBS_DROPDOWNLIST,这将使ComboBox只能从下拉列表中选择已定义的值。 2. 在OnInitDialog()函数中,使用AddString()函数向ComboBox中添加所有可选项的字符串。 3. 在ComboBox下拉事件OnCbnDropdown()中,遍历ComboBox中所有的项,如果该项的字符串不在指定字符串列表中,就使用DeleteString()函数删除该项。 以下是示例代码: ``` // 在窗口类的头文件中定义指定字符串数组 CStringArray m_arrStrings; // 在OnInitDialog()函数中添加ComboBox控件 CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBOBOX); pComboBox->ModifyStyle(0, CBS_DROPDOWNLIST); // 向ComboBox中添加所有可选项的字符串 pComboBox->AddString(_T("Option 1")); pComboBox->AddString(_T("Option 2")); pComboBox->AddString(_T("Option 3")); // 在ComboBox下拉事件OnCbnDropdown()中过滤不需要的项 void CMyDialog::OnCbnDropdownCombo() { CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBOBOX); int nCount = pComboBox->GetCount(); for (int i = nCount - 1; i >= 0; i--) { CString strText; pComboBox->GetLBText(i, strText); if (m_arrStrings.Find(strText) == -1) { pComboBox->DeleteString(i); } } } ``` 在上述示例代码中,OnCbnDropdownCombo()函数中的m_arrStrings是指定的字符串数组。在ComboBox下拉事件中,遍历ComboBox中的所有项,如果该项的字符串不在指定字符串列表中,就使用DeleteString()函数删除该项。这样ComboBox就只会显示指定字符串列表中的内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值