'DataGrid'에 해당되는 글 3건
2009. 6. 23. 09:57
DataGrid는 다음과 같이 간편하게 표형식의 데이터를 화면에 출력할 수 있습니다.


이런 DataGrid은 위의 코드에서 보실 수 있듯, DataGridColumn 을 이용하여 화면에 각 열을 생성하여 보여지게 됩니다. 데이터가 아무리 많이 들어오더라도 DataGridColumn이 지정되어 있지 않으면 출력되지 않죠. DataGridColumn은 가장 기본적으로 headerText, dataField 속성을 필요로 합니다.

headerText : DataGrid의 헤더(Header)에 출력될 문자열. 값이 지정되지 않을 경우 dataField의 값으로 사용합니다.
dataField : DataGrid에 입력된 데이터(DataProvider)에서 해당 열에 출력될 데이터를 지정.

위의 코드와 같이 MXML로 정의된 DataGridColumn의 정보(headerText 나 dataField, 혹은 넓이정보 등)를 변경하고자 한다면 어떻게 해야할까요? 방법은 여러가지일 수 있으나, 크게 본다면 1. DataGridColumn에 ID를 지정하여 해당 ID로 접근하거나 2. DataGrid의 columns 속성을 이용하여 DataGridColumn 모음을 받아와 처리하는 방법이 있을 수 있겠습니다.
이 포스트에서는 2번째 방법인 columns속성을 이용하는 것을 알아보도록 하겠습니다.

columns 속성은 DataGrid의 화면에 출력될 수 있는 하나 이상의 DataGridColumn들을 모아놓은 배열입니다. 이 배열에 담겨있는 DataGridColumn들을 수정하면 DataGrid의 모습도 바뀌게 된다는 것이죠.  특정 컬럼을 변경하고자 하면 이 배열의 해당 DataGridColumn에 대해 변경을 하면 반영이 되게 됩니다.

만약 위의 MXML처럼 ActionScript로 DataGridColumn을 설정하려 한다면 columns 속성에 직접 다음과 같이 DataGridColumn을 넣어주면 됩니다.

makeDataGridColumn 이라는 DataGridColumn 객체를 반환하는 메소드를 이용하여 DataGrid의  columns 속성에 원하는 DataGridColumn을 배열로 담아 넣어주게 되면 처음에 보셨던 MXML에서 DataGridColumn을 지정하는 것과 같이 처리할 수 있게 되죠.

마지막으로 원하는 컬럼의 headerText 를 변경하는 예제를 만들어보고 이 포스트를 끝내도록 하겠습니다.
우선 원하는 컬럼을 선택하는 용도로 사용할 ComboBox를 생성 후, 컬럼에 대한 정보를 columns 속성을 이용하여 ComboBox에 넣도록 하겠습니다.


거기에 TextInput 과 Button을 생성하여 변경하고자 하는 문자열을 입력받고 동작할 수 있게 changeLabel 메소드를 추가합니다.


완성된 코드 및 SWF 파일입니다. ;)

좋은 하루 보내세요~ ;)
2008. 4. 22. 14:21
Flex 의 DataGrid 는 상당히 유용한 컴포넌트입니다. 표 형태의 데이터를 출력하기 참 좋거든요.
이때 출력된 데이터중에 어떤 한 데이터를 출력하여 그 데이터에 대해서 작업을 해야할 때가 있습니다.
예를 들어 게시판의 글을 클릭하여 그 글을 보고자 하는 App를 작성한다고 합시다.

이때 보통 아래의 소스와 같이 DataGrid의 click 이벤트를 이용합니다.



click="clickEventHandler(event)" 라고 정의하여 해당 DataGrid 가 클릭되었을때 clickEventHandler() 메소드를 호출하게 됩니다.
이 해당 메소드는 다음과 같이 정의하였습니다.


하지만 위의 처리방식에는 문제가 있습니다.
clickEventHandler() 메소드에서 DataGrid의 selectedItem 속성을 이용하여 선택된 아이템에 접근하게 되는데, 만약 아무런 값이 없는 곳을 클릭한다면 어떻게 될까요? 이 때도 click 이벤트는 발생하게 되어 clickEventHandler() 메소드가 호출되겠지만, 선택된 아이템이 없으니 selectedItem 은 null 이 되게 됩니다. 그렇기에 위의 소스 6번째 줄의 selectedItem.url에서 에러가 발생하게 됩니다.
(헤더를 클릭해도 에러가 납니다. -- 추가)

물론 try catch 문을 이용하여 에러처리를 하면 됩니다만, 발생할 것이 예상되는 에러를 예외처리한다는 것은 그리 권장할 만한 방법이 아닙니다.

에러가 발생하지 않으면 Alert 창이 떠야하지만, 에러가 발생해서 Alert 창이 뜨지 않습니다. debug 용 flash player 를 설치하신 분은 다음의 에러메세지를 보실 수 있습니다.
TypeError: Error #1009: null 객체 참조의 속성이나 메서드에 액세스할 수 없습니다.
 at ClickTest/clickEventHandler()
 at ClickTest/__myDG_click()
 

이런 경우 실제 필요한건 아이템을 선택하는 것이지 DataGrid를 선택하는 것이 아닙니다.
이럴때 사용하기 좋은 이벤트가 바로 itemClick 이벤트 입니다.

itemClick event 
유저가 컨트롤내의 아이템을 클릭했을 때에 dispatch됩니다.
ListEvent.ITEM_CLICK 정수는,itemClick 이벤트에 관한 ListEvent object의 type property의 값을 정의합니다. 이 이벤트는, 컨트롤내의 가시 아이템 위에서 유저가 마우스를 클릭한 것을 나타냅니다.
출처 : flexdocs.kr

click 이벤트 대신 itemClick 이벤트를 이용하여 동일한 어플을 만든다면 위와 같은 문제는 해결되게 됩니다.
(Flex 3는 아닙니다만, Flex 2 에서는 DataGrid의 Header를 클릭해도 itemClick 이벤트가 발생됩니다. 완전히 해결은 안되는군요. 의견주신 유영상님 감사드립니다. - 추가) 
아래는 최종 샘플코드입니다.





더블클릭시 사용할 수 있는 itemDoubleClick 이벤트도 있으니 참고하시길 바랍니다.

ps. 쓰다보니 또 길어졌네요.. 별 내용 아닌데.. ㅜㅜ
2007. 11. 20. 15:56
다음의 포스팅은 Peter Ent 블로그Coloring the Background of Cells 포스트의 검쉰 맘대로 해석판입니다.
말이 안되게 타이프 해놓은 것도 있으니(ㅡㅡ;) 그러려니... 하여 주세요 ;)

아래의 결과물은 해당 포스트의 소스를 빌드하여 올려보았습니다.



위의 예제는 총 5개로 되어 있습니다만, 4개만 설명 합니다.
1. 아이템렌더러(itemRenderer)를 이용하여 특정컬럼의 배경색을 바꾸기 (itemRenderer Tab)
2. 컬럼에 직접 배경색을 지정하기 (backgroundColor Tab)
3. drawColumnBackground function을 재정의하여 배경색에 alpha 값을 주기 (backgroundAlpha Tab)
4. drawRowBackground function을 재정의하여 row에 배경색을 주기 (Custom Row Background Tab)



1. 아이템 렌더러(itemRenderer)를 이용하여 특정 컬럼의 배경색을 바꾸기 
   (itemRenderer Tab 참고)

특정 Cell의 배경색을 바꾸려면 아이템렌더러(itemRenderer)가 필요합니다.
아이템렌더러(itemRenderer)는 데이터그리드(Datagrid)의 전체에 적용하거나 특정 컬럼에 적용이 가능합니다만,
아래의 아이템렌더러(itemRenderer) 예제에는 Year 컬럼에만 적용하도록 하겠습니다.

간단하게 Label을 상속받아 updateDisplayList function을 재정의 하여서
Year의 값을 판단(Year의 값이 2000년 이전이면 파란색, 2000년 이후이면 녹색) 하여
Label에 파란색 또는 녹색의 사각형을 그려 배경색을 나타내고 있습니다.

<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Script>
    <![CDATA[

      import flash.geom.Matrix;
      import flash.display.GradientType;
      import flash.display.Graphics;

      override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
      {
        super.updateDisplayList(unscaledWidth,unscaledHeight);

        var m:Matrix = new Matrix();
        m.createGradientBox(unscaledWidth,unscaledHeight);

        var g:Graphics = graphics;
        var colors:Array = (data.col3 < 2000 ? [0x0000CC,0x0000FF] : [0x00CC00,0x00FF00]);

        g.clear();
        g.beginGradientFill(GradientType.LINEAR, colors, [0.2,0.6], [0,255], m);
        g.drawRect(0, -2, unscaledWidth, unscaledHeight+4 );
        g.endFill();
      }
    ]]>
  </mx:Script>
</mx:Label>

아래는 AS Class 로 동일하게 만들어본 아이템 렌더러입니다.
package
{
  import flash.geom.Matrix;
  import flash.display.GradientType;
  import flash.display.Graphics;
  import mx.controls.Label;

  public class ColoredBackgroundItemRenderer extends Label
  {
    public function ColoredBackgroundItemRenderer()
    {
      super();
    }

    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
      super.updateDisplayList(unscaledWidth,unscaledHeight);

      var m:Matrix = new Matrix();
      m.createGradientBox(unscaledWidth,unscaledHeight);

      var g:Graphics = graphics;
      var colors:Array = (data.col3 < 2000 ? [0x0000CC,0x0000FF] : [0x00CC00,0x00FF00]);

      g.clear();
      g.beginGradientFill(GradientType.LINEAR, colors, [0.2,0.6], [0,255], m);
      g.drawRect(0, -2, unscaledWidth, unscaledHeight+4 );
      g.endFill();
    }
  }
}



2. 컬럼에 직접 배경색을 지정하기
   (backgroundColor Tab 참고)




단지 컬럼의 모든 Cell에 배경색을 지정하고 싶은 것이라면 아이템 렌더러를 만들 필요는 없습니다.
아래와 같이 데이터그리드(Datagrid) 컬럼에 있는 backgroundColor 속성을 이용하면 쉽게 가능합니다.

<mx:DataGridColumn headerText="Make" backgroundColor="0xCC0000" dataField="col1"/>

0xCC0000은  빨강색() 입니다. backgroundColor Tab에서 Make 컬럼에 적용되어 있습니다.
backgroundColor="red" 같은 경우도 가능합니다.



3. drawColumnBackground function을 재정의하여 배경색에 alpha 값을 주기
   (backgroundAlpha Tab 참고)



데이터그리드(Datagrid) 컬럼은 투명도(Alpha)를 주는 속성이 없습니다.
하지만  데이터그리드(Datagrid)에 있는 drawColumnBackground function을 재정의하여 투명도를 줄 수 가 있습니다.
데이터그리드(Datagrid)를 상속받아서 만든 Class에서 아래와 같이 drawColumnBackground function을 재정의 합니다.

override protected function drawColumnBackground(s:Sprite, columnIndex:int, color:uint, column:DataGridColumn):void
{
  super.drawColumnBackground(s,columnIndex,color,column);

  var background:Shape = Shape(s.getChildByName(columnIndex.toString()));
 
  if( background )
  {
    background.alpha = 0.5;
  }
}

하지만 위의 코드에서는 투명도가 0.5로 하드코딩 되어 있으므로 권장할 만한 코드가 안됩니다.
그래서 다음과 같이 Class 내에 투명도를 저장할 변수 columnBackgroundAlpha를 정의합니다.

public var columnBackgroundAlpha:Number = 1;

그리고 재정의한 drawColumnBackground function의 코드를 변수 columnBackgroundAlpha에 의해
투명도를 변경할 수 있도록 다음과 같이 수정합니다.

backgroundAlpha = columnBackgroundAlpha;

외부에서 투명도는 아래와 같이 변경 할 수 있습니다.

<local:ColoredBackgroundDataGrid columnBackgroundAlpha="0.3" ... >



4. drawRowBackground function을 재정의하여 row에 배경색을 주기
   (Custom Row Background Tab 참고)


특정 컬럼이 아닌 한 줄(row)의 배경색을 바꾸려면 데이터그리드(Datagrid)를 상속받은 Class에서
아래와 같이 drawRowBackground function을 재정의 하여 배경색을 바꿀 수 있습니다.

year의 값이 2000년 이전이면 오렌지색, 2000년 이후면 흰색, 값이 없으면 녹색으로 출력하도록 하였습니다.

override protected function drawRowBackground(s:Sprite, rowIndex:int, y:Number, height:Number, color:uint, dataIndex:int):void
{
  var dp:ArrayCollection = dataProvider as ArrayCollection;
  var item:Object;

  if( dataIndex < dp.length ) item = dp.getItemAt(dataIndex);

  if( item != null && item.year < 20000 ) color = 0xFF8800;
  else if( item != null && item.year>= 2000 ) color = 0xFFFFFF;
  else color = 0x00CC00;

  super.drawRowBackground(s,rowIndex,y,height,color,dataIndex);
}

하지만, 위의 코드는 색깔과 기준값들이 하드코딩되어 있어 권장할만한 코드가 못됩니다.
이 때, 배경색으로 쓰일 색을 외부에서 따로 구현할 수 있도록 하여 해결하도록 하겠습니다.

외부의 function을 쓰기 위해 Class에 아래와 같이 속성을 하나 추가하겠습니다.

public var rowColorFunction:Function;

그리고 아래와 같이 color값을 위에서 만든 Function에서 받아올 수 있도록 하여 줍니다.

override protected function drawRowBackground(s:Sprite, rowIndex:int, y:Number, height:Number, color:uint,dataIndex:int):void
{
  if( rowColorFunction != null )
  {
    var dp:ArrayCollection = dataProvider as ArrayCollection;
    var item:Object;
   
    if( dataIndex < dp.length ) item = dp.getItemAt(dataIndex);

    color = rowColorFunction( item, rowIndex, dataIndex, color );
  }
 
  super.drawRowBackground(s,rowIndex,y,height,color,dataIndex);
}

그리고 아래와 같이 rowColorFunction에 외부의 function을 지정하여 주고,

<local:ColoredBackgroundDataGrid rowColorFunction="determineColor" ... >

지정된 determineColor function은 아래와 같이 정의합니다.

private function determineColor( item:Object, rowIndex:int, dataIndex:int, oldColor:uint ) : uint
{
  if( item == null ) return 0x00CC00; // green are empty rows
  if( item.year< 2000 ) return 0xFFCC00;
  else if( item.year >= 2000 ) return 0xFFFFFF;
}

이제 정의 하였던 Class 외부에서 rowColorFunction에 알맞는 function을 정의하여 배경색을 변경 할 수 있게 되었습니다.
prev"" #1 next