在OnChange事件里设置ComboBox的Text内容(200分)

  • 主题发起人 主题发起人 风卷残月
  • 开始时间 开始时间

风卷残月

Unregistered / Unconfirmed
GUEST, unregistred user!
如 ComboBox控件里原有内容
11111
22222
33333
要求无论选择一项后 将控件Text内容改为 '44444'
直接在OnChange里改的话没用,偶也试过默认的几个事件,都不行,控件会根据用户选择项的ItemIndex更改Text的值.
其实问题已经解决,为了感谢帮助的朋友,嘿嘿.
 
怎么解决的呢
 
[:D]等会再发上来,下班结贴
 
非常简单啊,加一个TIMER就可以了:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
ComboBox1: TComboBox;
Timer1: TTimer;
procedure ComboBox1Change(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
timer1.Enabled:=true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
timer1.Interval:=50;
timer1.Enabled:=false;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
ComboBox1.Text:='4444';
timer1.Enabled:=false;
end;

end.
 
"要求无论选择一项后 将控件Text内容改为 '44444'" 不要用那种怪方法吧, 或者要求改为 要在Text 上显示相应的ItemIndex号,这样就稍微动态一点了
 
现在就结帖得了
 
楼主可以把第一项的值设为'4444'.
然后在ComboBoxSelect事件里写:ComboBox.ItemIndex := 0;
这样就可以了.
注意处理内容时要除掉第一行即可.
如果觉得这样不好看.可以用一个变量临时记录第一行的值,再设置第一行的值为'4444'.在需要时再将变量的值赋回.
 
那楼主把你的方法SHOW一下,呵呵,我只是随便写的,没有仔细想。
 
ComboBox的信息格式: StringLeft | StringRight
分为左右两个串, 而选中其中一个时只需要在ComboBox上显示 StringLeft,所以才有了这个问题.
首先不能在OnChange事件里面直接赋值,因为你赋完值以后ComboBox会根据刚才选中的ItemIndex而设置Text属性的, 所以直接在OnChange事件里赋值的想法不成立. 而OnCloseUp,Click这些事件发生都在OnChange事件之前,想想都懂肯定不行,当然也可以用 获取StringLeft,然后用Add的方法添加到ComboBox,再更改ItemIndex的方法来显示.且当用户再次点击 ComboBox的时候再把那项删除. 虽然这样做稍微麻烦一点, 但还是可以实现.
不过既然我们是学这行的,遇到问题不可能都逃避吧,在时间比较充分的情况下还是能解决尽量,同时又可以学到东西不是:)

下面是 lichengbin老大给出的方法:
在OnChange事件里:
PostMessage(Handle, WM_USER + 100, 0, 0);

而后在窗体中加入
procedure CMComboText(var Message: TMessage); message WM_USER + 100;

下面是实现代码
procedure TForm_product_detail.CMComboText(var Message: TMessage);
Var
StringLeft: String;
begin
Inherited;
StringLeft:= GetStringLeft; //GetStringLeft为自定义函数,是取StringLeft的
ComboBox_Order.Text := StringLeft;
end;


这样就实现了OnChange 后ComboBox.Text的更改, 不信试下,
为什么会这样呢,到目前为止自己还是有点不大清楚, 属于半晕状态, 回去好好翻下书
但感觉上消息队列的问题, 自己的理解是可以将消息队列分层次,在OnChange事件中用户已经更改了选项, 但控件并没有马上更改Text的值(他是在OnChange事件执行完后才更改Text的值,到底是哪个消息就不懂了,感兴趣的朋友可以试一下), 而PostMessage是发消息到消息队列中就不管了的,这感觉上就有了一段延时, 就那个那消息处理过程里更改ComboBox的Text. 写到这里心中就有一个疑问了,这好像就是一个延时更改嘛,就相当于启动一个Timer,然后设定延时时间为多少, 等到时间到了以后由Timer来获取更改StringLeft,更改完毕以后将自己 Enalbed := False, 感觉都有点类似的效果,自己也在PostMessage后面加一个 ShowMessage测试, 结果和想像中的一样, Text 还是 = StringLeft | StringRight, 问题不用多说了吧,就是PostMessage. 但也不能用SendMessage ,因为SendMessage 要等到消息被执行才返回, OnChange 没结束,ComboBox是不会更改 Text的值的, 用SendMessage 和直接赋值没什么区别.
引用lichengbin 本人的话就是"關鍵就在消息處理的先後順序上面了". 他说还有别的方法,比如 subclass子類化 这方面的. 只不過PostMessage的方法最簡便是了 [:D]
 
算了,残月这么诚心发分,不领实在是对不起他的好意和劳苦大众,给个简单的方法吧:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
ComboBox1: TComboBox;
procedure ComboBox1Click(Sender: TObject);
private
{ Private declarations }
procedure CMComboText(var Message: TMessage); message WM_USER+100;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CMComboText(var Message: TMessage);
begin
ComboBox1.Text := '4444';
end;

procedure TForm1.ComboBox1Click(Sender: TObject);
begin
PostMessage(Handle, WM_USER+100, 0, ComboBox1.ItemIndex);
end;

end.
 
其实OnClick和OnChange 一样的, 这点偶也有点疑惑, 回去翻翻书,搞清楚,今天买了路由器,晚上可以上网了, 嘿嘿~~`
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部