本帖最后由 fox600123 于 2013-02-23 23:42:36 编辑

解决方案 »

  1.   


    我想知道你放那个Panel的用意是什么?
      

  2.   

    没找到办法啊。你看下这样能不能满足你的要求:
    AdvStringGrid1.MergeCells(1, 1, 10, 1);
    AdvStringGrid1.CellControls[1, 1] := Panel1;如果不用Controls这个属性,应该有其他办法能实现你要的功能。
      

  3.   


    我想在panel1上搭载60*3=180个listbox,系统共需14个panel共2520个listbox
    其实AdvStringGrid每个cell对应一个listbox是最好的,但这样会有两个问题
    1.会把listbox的拖拽事件屏蔽掉,而我恰好需要拖拽功能
    2.AdvStringGrid每个cell对应一个listbox系统花销太大,初始化就需要1分钟,拖动出现显示断裂现象
    而先在AdvStringGrid上放置panel再在panel上放listbox则能解决这两个问题,可又出现了刚才说的panel挡住advstringgrid的问题,也是最后一个没解决的问题了~
      

  4.   

    这种,完全在Timage上画更好(灵活)吧?
    只是需要自己处理滚动
      

  5.   


    那你可以每个Panel搭载一个ListBox是试下,不要搭载3个;不过这样真的很耗内存,严重影响性能;我是觉得可以不用Panel和ListBox,可以用AdvStringGrid的重画功能可以实现你的功能。
      

  6.   

    就3个操作:画字,画白底,画边框拖曳功能可以用AdvStringGrid的拖曳功能
      

  7.   


    方法一:修改AdvStringGird的代码:
    在unit AdvGrid中找到TopLeftChanged函数,然后修改为如下procedure TAdvStringGrid.TopLeftChanged;
      function CellRectEx(c,r: integer): TRect;//自己新增的CellRectEx函数
      var
        r1, r2: TRect;
        BC, pSpan: TPoint;
      begin
        if HasCellProperties(c,r) then
          if (CellProperties[c,r].CellSpanX <> -1) or (CellProperties[c,r].CellSpanY <> -1) then
          begin
            BC := BaseCell(c,r);
            pSpan.X := CellProperties[BC.X,BC.Y].CellSpanX;
            pSpan.Y := CellProperties[BC.X,BC.Y].CellSpanY;
            if BC.X < LeftCol then
            begin
              pSpan.X := pSpan.X - (LeftCol - BC.X);
              BC.X := LeftCol;
            end;
            if BC.Y < TopRow then
            begin
              pSpan.Y := pSpan.Y - (TopRow - BC.Y);
              BC.Y := TopRow;
            end;
            r1 := GetCellRect(BC.X,BC.Y);
            r2 := GetCellRect(BC.X + pSpan.X,BC.Y + pSpan.Y);        UnionRect(r1, r1, r2);
            Result := r1;
          end
          else
            Result := GetCellRect(c,r)
        else
          Result := GetCellRect(c,r);
      end;
    var
      i,j: Integer;
      r: TRect;
      ctrl: TControl;
    begin
      inherited TopLeftChanged;
      if (EditMode) and (EditControl <> edNormal) then
        HideInplaceEdit;
      UpdateVScrollBar;
      UpdateHScrollBar;
      UpdateFooter;  for i := FOldLeftCol to FOldLeftCol + VisibleColCount do
        for j := FOldTopRow to FOldTopRow + VisibleRowCount do
        begin
          if (i < LeftCol) or (i > LeftCol + VisibleColCount) or
             (j < TopRow) or ( j > TopRow + VisibleRowCount) then
          begin
            ctrl := CellControls[i,j];
            if Assigned(ctrl) then
            begin
              r := CellRect(i,j);
              ctrl.SetBounds(r.Left,r.Top,0,0);
            end;
          end;
        end;  for i := LeftCol to LeftCol + VisibleColCount do
        for j := TopRow to TopRow + VisibleRowCount do
        begin
            ctrl := CellControls[i,j];
            if Assigned(ctrl) then
            begin
              r := CellRectEx(i,j);//修改成自己加的CellRectEx
              ctrl.SetBounds(r.Left,r.Top,r.Right - r.Left,r.Bottom - r.Top);
            end;
        end;  FOldLeftCol := LeftCol;
      FOldTopRow := TopRow;
    end;方法二,继承TAdvStringGrid,全部代码如下,但是,不知为啥,继承后的控件就是不执行我重载的函数TopLeftChanged;有高手在的话也帮忙看下为什么,觉得继承TAdvStringGrid的方式比较好,不会修改到TAdvStringGrid的源码。unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids, BaseGrid, AdvGrid, StdCtrls, ExtCtrls;type
      TMyAdvStringGrid = class(TAdvStringGrid)
      private
      protected
        procedure TopLeftChanged; reintroduce;
      public
        constructor Create(AOwner:TComponent); override;
      end;  TForm1 = class(TForm)
        Button1: TButton;
        AdvStringGrid1: TAdvStringGrid;
        Panel1: TPanel;
        Edit1: TEdit;
        Panel2: TPanel;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
        MyAdvStringGrid1: TAdvStringGrid;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    var
      i: integer;
    begin
      MyAdvStringGrid1 := TAdvStringGrid.Create(Self);
      MyAdvStringGrid1.Parent := Self;
      MyAdvStringGrid1.SetBounds(100, 100, 680, 200);
      MyAdvStringGrid1.DefaultColWidth := 30;
      MyAdvStringGrid1.ColCount := 30;
      for i := 1 to AdvStringGrid1.RowCount - 1 do
        MyAdvStringGrid1.Cells[0, i] := IntToStr(i);
      for i := 1 to AdvStringGrid1.ColCount - 1 do
        MyAdvStringGrid1.Cells[i, 0] := IntToStr(i);  Panel1.Parent := MyAdvStringGrid1;
      MyAdvStringGrid1.MergeCells(1, 1, 10, 1);
      MyAdvStringGrid1.CellControls[10, 1] := Panel1;  AdvStringGrid1.MergeCells(1, 1, 10, 1);
      AdvStringGrid1.CellControls[10, 1] := Panel2;
      for i := 1 to AdvStringGrid1.ColCount - 1 do
        AdvStringGrid1.Cells[i, 0] := IntToStr(i);
    end;{ TMyAdvStringGrid }constructor TMyAdvStringGrid.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
    end;procedure TMyAdvStringGrid.TopLeftChanged;
      function CellRectEx(c,r: integer): TRect;
      var
        r1, r2: TRect;
        BC, pSpan: TPoint;
      begin
        if IsMergedCell(c,r) then
        begin
          BC := BaseCell(c,r);
          pSpan := CellSpan(c, r);
          if BC.X < LeftCol then
          begin
            pSpan.X := pSpan.X - (LeftCol - BC.X);
            BC.X := LeftCol;
          end;
          if BC.Y < TopRow then
          begin
            pSpan.Y := pSpan.Y - (TopRow - BC.Y);
            BC.Y := TopRow;
          end;
          r1 := GetCellRect(BC.X,BC.Y);
          r2 := GetCellRect(BC.X + pSpan.X,BC.Y + pSpan.Y);      UnionRect(r1, r1, r2);
          Result := r1;
        end
        else
          Result := GetCellRect(c,r);
      end;
    var
      i,j: Integer;
      r: TRect;
      ctrl: TControl;
    begin
      inherited TopLeftChanged;  for i := LeftCol to LeftCol + VisibleColCount do
        for j := TopRow to TopRow + VisibleRowCount do
        begin
            ctrl := CellControls[i,j];        if Assigned(ctrl) then
            begin
              r := CellRectEx(i,j);
              ctrl.SetBounds(r.Left,r.Top,r.Right - r.Left,r.Bottom - r.Top);
            end;
        end;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      if Assigned(MyAdvStringGrid1) then
        FreeAndNil(MyAdvStringGrid1);
    end;end.
      

  8.   

    方法二可以了,不用修改AdvStringGrid的源码来了,代码如下:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids, BaseGrid, AdvGrid, StdCtrls, ExtCtrls;type
      TMyAdvStringGrid = class(TAdvStringGrid)
      private
      protected
        procedure TopLeftChanged; override;
      public
        constructor Create(AOwner:TComponent); override;
      end;  TForm1 = class(TForm)
        Button1: TButton;
        AdvStringGrid1: TAdvStringGrid;
        Panel1: TPanel;
        Edit1: TEdit;
        Panel2: TPanel;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
        MyAdvStringGrid1: TMyAdvStringGrid;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    var
      i: integer;
    begin
      MyAdvStringGrid1 := TMyAdvStringGrid.Create(Self);
      MyAdvStringGrid1.Parent := Self;
      MyAdvStringGrid1.SetBounds(100, 100, 680, 200);
      MyAdvStringGrid1.DefaultColWidth := 30;
      MyAdvStringGrid1.ColCount := 30;
      for i := 1 to MyAdvStringGrid1.RowCount - 1 do
        MyAdvStringGrid1.Cells[0, i] := IntToStr(i);
      for i := 1 to MyAdvStringGrid1.ColCount - 1 do
        MyAdvStringGrid1.Cells[i, 0] := IntToStr(i);  Panel1.Parent := MyAdvStringGrid1;
      MyAdvStringGrid1.MergeCells(1, 1, 10, 1);
      MyAdvStringGrid1.CellControls[10, 1] := Panel1;  AdvStringGrid1.MergeCells(1, 1, 10, 1);
      AdvStringGrid1.CellControls[10, 1] := Panel2;
      for i := 1 to AdvStringGrid1.RowCount - 1 do
        MyAdvStringGrid1.Cells[0, i] := IntToStr(i);
      for i := 1 to AdvStringGrid1.ColCount - 1 do
        AdvStringGrid1.Cells[i, 0] := IntToStr(i);
    end;{ TMyAdvStringGrid }constructor TMyAdvStringGrid.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
    end;procedure TMyAdvStringGrid.TopLeftChanged;
      function CellRectEx(c,r: integer): TRect;
      var
        r1, r2: TRect;
        BC, pSpan: TPoint;
      begin
        if IsMergedCell(c,r) then
        begin
          BC := BaseCell(c,r);
          pSpan := CellSpan(c, r);
          if BC.X < LeftCol then
          begin
            pSpan.X := pSpan.X - (LeftCol - BC.X);
            BC.X := LeftCol;
          end;
          if BC.Y < TopRow then
          begin
            pSpan.Y := pSpan.Y - (TopRow - BC.Y);
            BC.Y := TopRow;
          end;
          r1 := GetCellRect(BC.X,BC.Y);
          r2 := GetCellRect(BC.X + pSpan.X,BC.Y + pSpan.Y);      UnionRect(r1, r1, r2);
          Result := r1;
        end
        else
          Result := GetCellRect(c,r);
      end;
    var
      i,j: Integer;
      r: TRect;
      ctrl: TControl;
    begin
      inherited TopLeftChanged;  for i := LeftCol to LeftCol + VisibleColCount do
        for j := TopRow to TopRow + VisibleRowCount do
        begin
            ctrl := CellControls[i,j];        if Assigned(ctrl) then
            begin
              r := CellRectEx(i,j);
              ctrl.SetBounds(r.Left,r.Top,r.Right - r.Left,r.Bottom - r.Top);
            end;
        end;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      if Assigned(MyAdvStringGrid1) then
        FreeAndNil(MyAdvStringGrid1);
    end;end.