델파이

DBGrid 컬럼 Width 화면 크기에 따라 자동 변경하기

미스터몽키 2019. 3. 5. 02:31

배움에는 끝이 없는 것 같다. 유레카~

오래 전부터 DBGrid 컬럼의 Width 값이 화면 크기에 따라 적당하게 변경되면 좋겠다는 생각을 했었다.

그동안 DBGrid 내에 여백이 있을 경우 맨 마지막 컬럼만 화면에 꽉차게 프로시저를 만들어 사용해 왔다.

그러나 오늘 구글링하다가 기발한 방법을 소개한 사이트를 찾았다. 블로그 스타일로 깔끔하게 설명과 코드도 잘 작성해 놓았다.


http://tech-story.net/fix-dbgrid-column-widths-automatically/


인터넷에 퍼져있는 대부분의 델파이 관련 내용은 예전에 작성한 것인데 최근한 작성한 것 처럼 깔끔하게 작성을 잘 해 놓았다. 

감사한 마음이다.


이 코드의 요점은 DBGrid의 컬럼 Width가 고정되어야 하는 것도 있고 화면 크기에 따라 변경되야 하는 것이 있다는

것이다.  

그도 그럴 것이 날짜나 금액 등 숫자와 관련된 것은 Width를 많이 차지하지 않고 고정되어도 된다.

가변 되어야하는 컬럼은 주로 문자열 컬럼으로 주소, 메모, 설명, 비고 같은 컬럼이다. 화면이 작을 때 전체 문자열 자리수 만큼 Width를 차지하면 너무 크게 차지하여 뒤 부분 컬럼이 안보이기도 하고 내용이 많기도 하고 없기도 하여 디자인타임에 Width설정이 항상 고민되곤 한다.


원래 소스에 Column Visible 속성 확인 추가하고 한글 주석을 달아 프로시저를 다시 작성해 보았다.


procedure TfrmDmSaky.FixDBGridColumnsWidth(const aDBGrid: TDBGrid);
// DBGrid 의 일부 컬럼은 Width를 고정하고 일부 컬럼은 Width를 화면 크기에 따라 변경하기.
// 1. 먼저 Column.Width를 고정할 컬럼은 DBGrid에 연결된 DataSet의 Field 속성 Tag 값을
//       0으로 하고 고정할 컬럼 Width 값을 디자인타임에 설정하고
// 2. 화면 크기에 따라 Width를 변경할 컬럼은 DBGrid에 연결된 DataSet의 Field 속성 Tag 
//    값을 최소한의 Column.Width 값으로 설정한다.
// 3. 본 프로시저를 DBGrid을 포함하는 상위 Panel 이나 Form 의 OnResize 이벤트에서 호출한다.
// 4. 고정 Column.Width는 화면 크기에 관계없이 항상 똑같고
// 5. 가변 컬럼은 화면이 커져 DBGrid 내부에 여백이 생기면 여백을 가변 컬럼 수 만큼 n 등분하여
//     각 가변컬럼의 최소값에 더한다.
// 6. 결국 DBGrid의 맨 마지막 컬럼 이후에 여백은 항상 꽉 채워진다.
var
  i : integer;
  TotWidth : integer;
  VarWidth : integer;
  ResizableColumnCount : integer;
  AColumn : TColumn;
begin
  TotWidth := 0;  // 모든 컬럼 Width 합   
  VarWidth := 0;  // 여백부분의 Width 값을 가변 컬럼 수 n등분한 값
  ResizableColumnCount := 0;  // 가변 컬럼 수   

  for i := 0 to -1 + aDBGrid.Columns.Count do
  begin
    if aDBGrid.Columns[i].Visible=True then
begin
TotWidth := TotWidth + aDBGrid.Columns[i].Width;

     if aDBGrid.Columns[i].Field.Tag > 0 then
       Inc(ResizableColumnCount);
end;
  end;

  //add 1px for the column separator line
  if dgColLines in aDBGrid.Options then
    TotWidth := TotWidth + aDBGrid.Columns.Count;

  //add indicator column width
  if dgIndicator in aDBGrid.Options then
    TotWidth := TotWidth + IndicatorWidth;

  //여백 Width 값
  VarWidth :=  aDBGrid.ClientWidth - TotWidth;

  if ResizableColumnCount > 0 then
    VarWidth := varWidth div ResizableColumnCount;  // n등분 여백 Width 값

  for i := 0 to -1 + aDBGrid.Columns.Count do
  begin
    AColumn := aDBGrid.Columns[i];

    if (AColumn.Visible=True) and (AColumn.Field.Tag > 0) then
    begin
      AColumn.Width := AColumn.Width + VarWidth;
      if AColumn.Width < AColumn.Field.Tag then
        AColumn.Width := AColumn.Field.Tag;
    end;
  end;
end;




위 프로시저를 DBGrid를 포함하는 Panel 이나 Form의 onResize 이벤트에서 호출하면 된다.

굿~


(참고1)

위와 조금 다른 것이데 DBGrid의 타이틀 텍스트 Width 만큼 혹은 실제 데이터 Width 만큼 자동으로

컬럼 Width 를 설정하는 방법도 있다. 하지만 실용적이지는 않는 것 같다. 세로 스크롤 할때 Width 가 변경되어

보기 안 좋다. 고정하고 싶은 컬럼 설정도 할수 없고...

그러나 소스는 간단하고 참고할 경우가 있을 것 같아 링크 걸어둔다.


https://stackoverflow.com/questions/13292937/how-to-auto-fit-scale-dbgrids-or-other-similar-columns-widths-according-to-it




(참고2)

현재 설정된 DBGrid 각 컬럼 Width 나 컬럼 순서를 저장하고 불러올 수 있는 메소드를 소개한다.


DBGrid1.Columns.SaveToFile('test.ini');


DBGrid1.Columns.LoadFromFile('test.ini');