DBCheckBox1: TDBCheckBox;procedure TForm1.DBCheckBox1Click(Sender: TObject);
begin
    DBCheckBox1.Checked:=not DBCheckBox1.Checked;//DBCheckBox1状态不变化
end;procedure TForm1.DBCheckBox1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
    DBCheckBox1.Checked:=not DBCheckBox1.Checked;//正常
end;
代码都一样结果为什么不一样?在click里写先是出错,要不就不变化,在mouseup里就正常,为什么?使用它要注意什么?

解决方案 »

  1.   

    事件发生的前后不同,此时的checkbox的状态也就不同了。
    你可以根据要求选用合适的事件处理。
      

  2.   

    当你单击一个CheckBox时,默认地,CheckBox的Check状态要发生反转,
    而此时你又在CheckBox的Click事件中改变了Check的值,
    所以CheckBox的Click事件实际上对在CheckBox的在Check值做了
    两次反转,这样的结果就是“DBCheckBox1状态不变化”
      

  3.   

    当你单击一个CheckBox时,默认地,CheckBox的Checked状态要发生反转,
    而此时你又在CheckBox的Click事件中改变了Checked的值,
    所以CheckBox的Click事件实际上对CheckBox的Checked值做了
    两次反转,这样的结果就是“DBCheckBox1状态不变化”
      

  4.   

    可能我没说清楚DBCheckBox1.Checked:=not DBCheckBox1.Checked;
    这一句在写在onmouseup里正常,如果改用在onclick里就不行了
    不是同时用
      

  5.   

    我還是不明白.
    你要把checkbox請空嗎使它處於無選擇狀態嗎?
    在click里写當然要出错了.因為在click中你要寫判斷是否在選擇狀態還是沒有.
      

  6.   

    To c_hk(小李抢刀)
    不是CheckBox,TDBCheckBox也没有从TCheckBox继承
    我直接放DBCheckBox在窗体上的话,单击DBCheckBox只是变灰又还原
    不知道为什么
      

  7.   

    c_hk(小李抢刀)说的已经很好了你这样可能让程序死循环
    procedure TForm1.DBCheckBox1Click(Sender: TObject);
    begin
        DBCheckBox1.Checked:=not DBCheckBox1.Checked;//DBCheckBox1状态不变化
    end;
      

  8.   

    这种情况并不像想象的那么简单明了。
    看一下源代码吧,tdbcheckbox继承自tcustomcheckbox继承自tcontrol
    onclick与onmouseup都来自wm_buttonup的消息处理。
    从消息处理函数来看,先触发的是onclick后是onmouseup
    procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
    begin
      inherited;
      if csCaptureMouse in ControlStyle then MouseCapture := False;
      if csClicked in ControlState then
      begin
        Exclude(FControlState, csClicked);
        if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;//触发click
      end;
      DoMouseUp(Message, mbLeft);//触发mouseup
    end;procedure TControl.Click;
    begin
      { Call OnClick if assigned and not equal to associated action's OnExecute.
        If associated action's OnExecute assigned then call it, otherwise, call
        OnClick. }
      if Assigned(FOnClick) and (Action <> nil) and (@FOnClick <> @Action.OnExecute) then
        FOnClick(Self)
      else if not (csDesigning in ComponentState) and (ActionLink <> nil) then
        ActionLink.Execute(Self)
      else if Assigned(FOnClick) then
        FOnClick(Self);
    end;procedure TControl.MouseUp(Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      if Assigned(FOnMouseUp) then FOnMouseUp(Self, Button, Shift, X, Y);
    end;可以看出两个触发事件之间并没做其他处理。
    疑惑中
    明天我再看看
      

  9.   

    楼上各位都说得很清楚了,如果确需这样做,你可以把DBCheckBox1的ReadOnly设为True;
      

  10.   

    DBCheckBox如果没有棒定数据对象的话,那么他的状态就是只读的!
    另外我需要解释一下,一个click事件,是鼠标的一次down跟up的结合。
    对于DBCheckBox来说,一个down以后,就马上改变状态,所以前面有人说的
    两次翻转状态,是正确的。
      

  11.   

    楼主,出现这种情况并不是因为像楼上大多数人所说的原因--触发onclick事件时Checked已经改变,我在前面贴了段源代码,恰恰说明Onclick与OnMouseUp是同时由同一个消息触发的。那么问题在哪呢?
    问题恰恰出在TCustomCheckBox上,一个很不让人注意的地方--FState的赋值函数中(如下)。从中可以看到当ClicksDisabled不是False时,又触发了OnClick事件。就是说每次改变Checked的值时都会触发OnClick事件(不知算不算BUG)而不会触发OnMouseUp事件。procedure TCustomCheckBox.SetState(Value: TCheckBoxState);
    begin
      if FState <> Value then
      begin
        FState := Value;
        if HandleAllocated then
          SendMessage(Handle, BM_SETCHECK, Integer(FState), 0);
        if not ClicksDisabled then Click;//触发OnClick事件
      end;
    end;
      

  12.   

    试了一下
    在checkbox的onclick事件中加入如下代码
     checkbox1.Checked:=not checkbox1.Checked;
    点击后程序陷入死循环直至报错:堆栈溢出(estackoverflow with message 'stack overflow')
    在dbcheckbox中设置datasource为ADOTable及field(一Bool型字段)属性,adotable连接并Active,在onclick事件中加入同样代码
      dbcheckbox1.Checked:=not dbcheckbox1.Checked;
    程序启动后直接死循环直至报错:堆栈溢出(estackoverflow with message 'stack overflow')测试环境:WindowsXP+Delphi6.0 enterprise
      

  13.   

    楼主,结贴时别忘了提交FAQ,这个问题还需要搞清楚。