使用TControlBar,如何将面板的移动限制在单行中?

4

我目前的项目需要使用TControlBar组件,但移动条带时会出现控件绘制额外行的问题,

基本上我想要的是ControlBar始终只有一个固定高度的行,并且当拖动条带时不能离开该行。

我该如何实现这个功能?


1
嗯,有人知道如何使用 OnBandInfo 事件,特别是 RowCount 参数吗?当设置为1时,它似乎并没有像我期望的那样限制行数。 - NGLN
我也尝试过调整 OnBandInfo,但效果不佳。我还发现设置 ControlBar 的 maxHeight 约束至少会在某种程度上改变带的绘制方式,但结果仍然是带会掉到新行中,只是不可见了。 - Peter
1
OnBandInfo的RowCount属性绝对不是答案,因为它仅控制该带横跨的行数,而不能实际控制该带可以停靠的行数。 - Peter
2个回答

0

你可以为此做一个变通方法:

procedure TForm1.ControlBar1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var R:TRect;
    Pt:TPoint;

begin
  Pt:=ControlBar1.ClientToScreen(Point(0,Y));
  R.Left:=Pt.X;
  R.Top:=Pt.Y;
  R.Right:=Pt.X+ControlBar1.Width;
  R.Bottom:=Pt.Y;
  ClipCursor(@R);
end;

procedure TForm1.ControlBar1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  ClipCursor(nil) ;
end;

通过这样,你可以限制鼠标移动,只允许带的垂直定位。


我反对任何全局限制,此外鼠标限制会导致可怕的最终用户体验,我不能容忍这种情况,更不用说在致命错误或崩溃的情况下结果是不可预测的。 - Peter

0

我几个月前解决了这个问题,基本上是通过从TPanel类派生自己的组件,并实现了一个拖动解决方案来模拟我想要的行为。

这是我用来实现所需效果的最基本原理:

var oldPos : TPoint;

procedure TMainForm.ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);

begin

   if Button = mbLeft then
     if (Sender is TWinControl) then
     begin
      inReposition:=True;
      SetCapture(TWinControl(Sender).Handle);
      GetCursorPos(oldPos);
      TWinControl(Sender).BringToFront;
     end else
        ((Sender as TLabel).Parent as TQPanelSub).OnMouseDown((Sender as TLabel).Parent as TQPanelSub,Button,Shift,X,Y)


end;


procedure TMainForm.ControlMouseMove(Sender: TObject; Shift: TShiftState; X: Integer; Y: Integer);
var
  newPos: TPoint;
  temp : integer;

begin

  if (Sender is TWinControl) then begin

    if inReposition then
    begin

      with TWinControl(Sender) do
      begin
        GetCursorPos(newPos);
        Screen.Cursor := crSize;
        (* Constrain to the container *)
        Top := 0;
        temp := Left - oldPos.X + newPos.X;
        if (temp >= 0) and (temp <= (Parent.Width - Width))
        then Left := temp;
        oldPos := newPos;
      end;

    end;

  end else
    ((Sender as TLabel).Parent as TQPanelSub).OnMouseMove((Sender as TLabel).Parent as TQPanelSub,Shift,X,Y);

end;

procedure TMainForm.ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);
begin

   if inReposition then
  begin
    Screen.Cursor := crDefault;
    ReleaseCapture;
    inReposition := False;
  end;

end;

这只是我想要从TControlBar中得到的基础,实际上它是一个写得非常糟糕的组件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接