Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/*** TDataGrid related class files.* This file contains the definition of the following classes:* TDataGrid, TDataGridItem, TDataGridItemCollection, TDataGridColumnCollection,* TDataGridPagerStyle, TDataGridItemEventParameter,* TDataGridCommandEventParameter, TDataGridSortCommandEventParameter,* TDataGridPageChangedEventParameter** @author Qiang Xue <qiang.xue@gmail.com>* @link http://www.pradosoft.com/* @copyright Copyright © 2005-2008 PradoSoft* @license http://www.pradosoft.com/license/* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls*//*** Includes TBaseList, TPagedDataSource, TDummyDataSource and TTable classes*/Prado::using('System.Web.UI.WebControls.TBaseDataList');Prado::using('System.Collections.TPagedDataSource');Prado::using('System.Collections.TDummyDataSource');Prado::using('System.Web.UI.WebControls.TTable');Prado::using('System.Web.UI.WebControls.TPanel');Prado::using('System.Web.UI.WebControls.TDataGridPagerStyle');/*** TDataGrid class** TDataGrid represents a data bound and updatable grid control.** To populate data into the datagrid, sets its {@link setDataSource DataSource}* to a tabular data source and call {@link dataBind()}.* Each row of data will be represented by an item in the {@link getItems Items}* collection of the datagrid.** An item can be at one of three states: browsing, selected and edit.* The state determines how the item will be displayed. For example, if an item* is in edit state, it may be displayed as a table row with input text boxes* if the columns are of type {@link TBoundColumn}; and if in browsing state,* they are displayed as static text.** To change the state of an item, set {@link setEditItemIndex EditItemIndex}* or {@link setSelectedItemIndex SelectedItemIndex} property.** Each datagrid item has a {@link TDataGridItem::getItemType type}* which tells the position and state of the item in the datalist. An item in the header* of the repeater is of type Header. A body item may be of either* Item, AlternatingItem, SelectedItem or EditItem, depending whether the item* index is odd or even, whether it is being selected or edited.** A datagrid is specified with a list of columns. Each column specifies how the corresponding* table column will be displayed. For example, the header/footer text of that column,* the cells in that column, and so on. The following column types are currently* provided by the framework,* - {@link TBoundColumn}, associated with a specific field in datasource and displays the corresponding data.* - {@link TEditCommandColumn}, displaying edit/update/cancel command buttons* - {@link TButtonColumn}, displaying generic command buttons that may be bound to specific field in datasource.* - {@link TDropDownListColumn}, displaying a dropdown list when the item is in edit state* - {@link THyperLinkColumn}, displaying a hyperlink that may be bound to specific field in datasource.* - {@link TCheckBoxColumn}, displaying a checkbox that may be bound to specific field in datasource.* - {@link TTemplateColumn}, displaying content based on templates.** There are three ways to specify columns for a datagrid.* <ul>* <li>Automatically generated based on data source.* By setting {@link setAutoGenerateColumns AutoGenerateColumns} to true,* a list of columns will be automatically generated based on the schema of the data source.* Each column corresponds to a column of the data.</li>* <li>Specified in template. For example,* <code>* <com:TDataGrid ...>* <com:TBoundColumn .../>* <com:TEditCommandColumn .../>* </com:TDataGrid>* </code>* </li>* <li>Manually created in code. Columns can be manipulated via* the {@link setColumns Columns} property of the datagrid. For example,* <code>* $column=new TBoundColumn;* $datagrid->Columns[]=$column;* </code>* </li>* </ul>* Note, automatically generated columns cannot be accessed via* the {@link getColumns Columns} property.** TDataGrid supports sorting. If the {@link setAllowSorting AllowSorting}* is set to true, a column with nonempty {@link setSortExpression SortExpression}* will have its header text displayed as a clickable link button.* Clicking on the link button will raise {@link onSortCommand OnSortCommand}* event. You can respond to this event, sort the data source according* to the event parameter, and then invoke {@link databind()} on the datagrid* to show to end users the sorted data.** TDataGrid supports paging. If the {@link setAllowPaging AllowPaging}* is set to true, a pager will be displayed on top and/or bottom of the table.* How the pager will be displayed is determined by the {@link getPagerStyle PagerStyle}* property. Clicking on a pager button will raise an {@link onPageIndexChanged OnPageIndexChanged}* event. You can respond to this event, specify the page to be displayed by* setting {@link setCurrentPageIndex CurrentPageIndex}</b> property,* and then invoke {@link databind()} on the datagrid to show to end users* a new page of data.** TDataGrid supports two kinds of paging. The first one is based on the number of data items in* datasource. The number of pages {@link getPageCount PageCount} is calculated based* the item number and the {@link setPageSize PageSize} property.* The datagrid will manage which section of the data source to be displayed* based on the {@link setCurrentPageIndex CurrentPageIndex} property.* The second approach calculates the page number based on the* {@link setVirtualItemCount VirtualItemCount} property and* the {@link setPageSize PageSize} property. The datagrid will always* display from the beginning of the datasource up to the number of* {@link setPageSize PageSize} data items. This approach is especially* useful when the datasource may contain too many data items to be managed by* the datagrid efficiently.** When the datagrid contains a button control that raises an {@link onCommand OnCommand}* event, the event will be bubbled up to the datagrid control.* If the event's command name is recognizable by the datagrid control,* a corresponding item event will be raised. The following item events will be* raised upon a specific command:* - OnEditCommand, if CommandName=edit* - OnCancelCommand, if CommandName=cancel* - OnSelectCommand, if CommandName=select* - OnDeleteCommand, if CommandName=delete* - OnUpdateCommand, if CommandName=update* - onPageIndexChanged, if CommandName=page* - OnSortCommand, if CommandName=sort* Note, an {@link onItemCommand OnItemCommand} event is raised in addition to* the above specific command events.** TDataGrid also raises an {@link onItemCreated OnItemCreated} event for* every newly created datagrid item. You can respond to this event to customize* the content or style of the newly created item.** Note, the data bound to the datagrid are reset to null after databinding.* There are several ways to access the data associated with a datagrid row:* - Access the data in {@link onItemDataBound OnItemDataBound} event* - Use {@link getDataKeys DataKeys} to obtain the data key associated with* the specified datagrid row and use the key to fetch the corresponding data* from some persistent storage such as DB.* - Save the data in viewstate and get it back during postbacks.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0*/class TDataGrid extends TBaseDataList implements INamingContainer{/*** datagrid item types* @deprecated deprecated since version 3.0.4. Use TListItemType constants instead.*/const IT_HEADER='Header';const IT_FOOTER='Footer';const IT_ITEM='Item';const IT_SEPARATOR='Separator';const IT_ALTERNATINGITEM='AlternatingItem';const IT_EDITITEM='EditItem';const IT_SELECTEDITEM='SelectedItem';const IT_PAGER='Pager';/*** Command name that TDataGrid understands.*/const CMD_SELECT='Select';const CMD_EDIT='Edit';const CMD_UPDATE='Update';const CMD_DELETE='Delete';const CMD_CANCEL='Cancel';const CMD_SORT='Sort';const CMD_PAGE='Page';const CMD_PAGE_NEXT='Next';const CMD_PAGE_PREV='Previous';/*** @var TDataGridColumnCollection manually created column collection*/private $_columns=null;/*** @var TDataGridColumnCollection automatically created column collection*/private $_autoColumns=null;/*** @var TList all columns including both manually and automatically created columns*/private $_allColumns=null;/*** @var TDataGridItemCollection datagrid item collection*/private $_items=null;/*** @var TDataGridItem header item*/private $_header=null;/*** @var TDataGridItem footer item*/private $_footer=null;/*** @var TPagedDataSource paged data source object*/private $_pagedDataSource=null;private $_topPager=null;private $_bottomPager=null;/*** @var ITemplate template used when empty data is bounded*/private $_emptyTemplate=null;/*** @var boolean whether empty template is effective*/private $_useEmptyTemplate=false;/*** @return string tag name (table) of the datagrid*/protected function getTagName(){return 'table';}/*** Adds objects parsed in template to datagrid.* Datagrid columns are added into {@link getColumns Columns} collection.* @param mixed object parsed in template*/public function addParsedObject($object){if($object instanceof TDataGridColumn)$this->getColumns()->add($object);elseparent::addParsedObject($object); // this is needed by EmptyTemplate}/*** @return TDataGridColumnCollection manually specified datagrid columns*/public function getColumns(){if(!$this->_columns)$this->_columns=new TDataGridColumnCollection($this);return $this->_columns;}/*** @return TDataGridColumnCollection automatically generated datagrid columns*/public function getAutoColumns(){if(!$this->_autoColumns)$this->_autoColumns=new TDataGridColumnCollection($this);return $this->_autoColumns;}/*** @return TDataGridItemCollection datagrid item collection*/public function getItems(){if(!$this->_items)$this->_items=new TDataGridItemCollection;return $this->_items;}/*** @return integer number of items*/public function getItemCount(){return $this->_items?$this->_items->getCount():0;}/*** Creates a style object for the control.* This method creates a {@link TTableStyle} to be used by datagrid.* @return TTableStyle control style to be used*/protected function createStyle(){return new TTableStyle;}/*** @return string the URL of the background image for the datagrid*/public function getBackImageUrl(){return $this->getStyle()->getBackImageUrl();}/*** @param string the URL of the background image for the datagrid*/public function setBackImageUrl($value){$this->getStyle()->setBackImageUrl($value);}/*** @return TTableItemStyle the style for every item*/public function getItemStyle(){if(($style=$this->getViewState('ItemStyle',null))===null){$style=new TTableItemStyle;$this->setViewState('ItemStyle',$style,null);}return $style;}/*** @return TTableItemStyle the style for each alternating item*/public function getAlternatingItemStyle(){if(($style=$this->getViewState('AlternatingItemStyle',null))===null){$style=new TTableItemStyle;$this->setViewState('AlternatingItemStyle',$style,null);}return $style;}/*** @return TTableItemStyle the style for selected item*/public function getSelectedItemStyle(){if(($style=$this->getViewState('SelectedItemStyle',null))===null){$style=new TTableItemStyle;$this->setViewState('SelectedItemStyle',$style,null);}return $style;}/*** @return TTableItemStyle the style for edit item*/public function getEditItemStyle(){if(($style=$this->getViewState('EditItemStyle',null))===null){$style=new TTableItemStyle;$this->setViewState('EditItemStyle',$style,null);}return $style;}/*** @return TTableItemStyle the style for header*/public function getHeaderStyle(){if(($style=$this->getViewState('HeaderStyle',null))===null){$style=new TTableItemStyle;$this->setViewState('HeaderStyle',$style,null);}return $style;}/*** @return TTableItemStyle the style for footer*/public function getFooterStyle(){if(($style=$this->getViewState('FooterStyle',null))===null){$style=new TTableItemStyle;$this->setViewState('FooterStyle',$style,null);}return $style;}/*** @return TDataGridPagerStyle the style for pager*/public function getPagerStyle(){if(($style=$this->getViewState('PagerStyle',null))===null){$style=new TDataGridPagerStyle;$this->setViewState('PagerStyle',$style,null);}return $style;}/*** @return TStyle the style for thead element, if any* @since 3.1.1*/public function getTableHeadStyle(){if(($style=$this->getViewState('TableHeadStyle',null))===null){$style=new TStyle;$this->setViewState('TableHeadStyle',$style,null);}return $style;}/*** @return TStyle the style for tbody element, if any* @since 3.1.1*/public function getTableBodyStyle(){if(($style=$this->getViewState('TableBodyStyle',null))===null){$style=new TStyle;$this->setViewState('TableBodyStyle',$style,null);}return $style;}/*** @return TStyle the style for tfoot element, if any* @since 3.1.1*/public function getTableFootStyle(){if(($style=$this->getViewState('TableFootStyle',null))===null){$style=new TStyle;$this->setViewState('TableFootStyle',$style,null);}return $style;}/*** @return string caption for the datagrid*/public function getCaption(){return $this->getViewState('Caption','');}/*** @param string caption for the datagrid*/public function setCaption($value){$this->setViewState('Caption',$value,'');}/*** @return TTableCaptionAlign datagrid caption alignment. Defaults to TTableCaptionAlign::NotSet.*/public function getCaptionAlign(){return $this->getViewState('CaptionAlign',TTableCaptionAlign::NotSet);}/*** @param TTableCaptionAlign datagrid caption alignment. Valid values include*/public function setCaptionAlign($value){$this->setViewState('CaptionAlign',TPropertyValue::ensureEnum($value,'TTableCaptionAlign'),TTableCaptionAlign::NotSet);}/*** @return TDataGridItem the header item*/public function getHeader(){return $this->_header;}/*** @return TDataGridItem the footer item*/public function getFooter(){return $this->_footer;}/*** @return TDataGridPager the pager displayed at the top of datagrid. It could be null if paging is disabled.*/public function getTopPager(){return $this->_topPager;}/*** @return TDataGridPager the pager displayed at the bottom of datagrid. It could be null if paging is disabled.*/public function getBottomPager(){return $this->_bottomPager;}/*** @return TDataGridItem the selected item, null if no item is selected.*/public function getSelectedItem(){$index=$this->getSelectedItemIndex();$items=$this->getItems();if($index>=0 && $index<$items->getCount())return $items->itemAt($index);elsereturn null;}/*** @return integer the zero-based index of the selected item in {@link getItems Items}.* A value -1 means no item selected.*/public function getSelectedItemIndex(){return $this->getViewState('SelectedItemIndex',-1);}/*** Selects an item by its index in {@link getItems Items}.* Previously selected item will be un-selected.* If the item to be selected is already in edit mode, it will remain in edit mode.* If the index is less than 0, any existing selection will be cleared up.* @param integer the selected item index*/public function setSelectedItemIndex($value){if(($value=TPropertyValue::ensureInteger($value))<0)$value=-1;if(($current=$this->getSelectedItemIndex())!==$value){$this->setViewState('SelectedItemIndex',$value,-1);$items=$this->getItems();$itemCount=$items->getCount();if($current>=0 && $current<$itemCount){$item=$items->itemAt($current);if($item->getItemType()!==TListItemType::EditItem)$item->setItemType($current%2?TListItemType::AlternatingItem:TListItemType::Item);}if($value>=0 && $value<$itemCount){$item=$items->itemAt($value);if($item->getItemType()!==TListItemType::EditItem)$item->setItemType(TListItemType::SelectedItem);}}}/*** @return TDataGridItem the edit item*/public function getEditItem(){$index=$this->getEditItemIndex();$items=$this->getItems();if($index>=0 && $index<$items->getCount())return $items->itemAt($index);elsereturn null;}/*** @return integer the zero-based index of the edit item in {@link getItems Items}.* A value -1 means no item is in edit mode.*/public function getEditItemIndex(){return $this->getViewState('EditItemIndex',-1);}/*** Edits an item by its index in {@link getItems Items}.* Previously editting item will change to normal item state.* If the index is less than 0, any existing edit item will be cleared up.* @param integer the edit item index*/public function setEditItemIndex($value){if(($value=TPropertyValue::ensureInteger($value))<0)$value=-1;if(($current=$this->getEditItemIndex())!==$value){$this->setViewState('EditItemIndex',$value,-1);$items=$this->getItems();$itemCount=$items->getCount();if($current>=0 && $current<$itemCount)$items->itemAt($current)->setItemType($current%2?TListItemType::AlternatingItem:TListItemType::Item);if($value>=0 && $value<$itemCount)$items->itemAt($value)->setItemType(TListItemType::EditItem);}}/*** @return boolean whether sorting is enabled. Defaults to false.*/public function getAllowSorting(){return $this->getViewState('AllowSorting',false);}/*** @param boolean whether sorting is enabled*/public function setAllowSorting($value){$this->setViewState('AllowSorting',TPropertyValue::ensureBoolean($value),false);}/*** @return boolean whether datagrid columns should be automatically generated. Defaults to true.*/public function getAutoGenerateColumns(){return $this->getViewState('AutoGenerateColumns',true);}/*** @param boolean whether datagrid columns should be automatically generated*/public function setAutoGenerateColumns($value){$this->setViewState('AutoGenerateColumns',TPropertyValue::ensureBoolean($value),true);}/*** @return boolean whether the header should be displayed. Defaults to true.*/public function getShowHeader(){return $this->getViewState('ShowHeader',true);}/*** @param boolean whether the header should be displayed*/public function setShowHeader($value){$this->setViewState('ShowHeader',TPropertyValue::ensureBoolean($value),true);}/*** @return boolean whether the footer should be displayed. Defaults to false.*/public function getShowFooter(){return $this->getViewState('ShowFooter',false);}/*** @param boolean whether the footer should be displayed*/public function setShowFooter($value){$this->setViewState('ShowFooter',TPropertyValue::ensureBoolean($value),false);}/*** @return ITemplate the template applied when no data is bound to the datagrid*/public function getEmptyTemplate(){return $this->_emptyTemplate;}/*** @param ITemplate the template applied when no data is bound to the datagrid* @throws TInvalidDataTypeException if the input is not an {@link ITemplate} or not null.*/public function setEmptyTemplate($value){if($value instanceof ITemplate || $value===null)$this->_emptyTemplate=$value;elsethrow new TInvalidDataTypeException('datagrid_template_required','EmptyTemplate');}/*** This method overrides parent's implementation to handle* {@link onItemCommand OnItemCommand} event which is bubbled from* {@link TDataGridItem} child controls.* If the event parameter is {@link TDataGridCommandEventParameter} and* the command name is a recognized one, which includes 'select', 'edit',* 'delete', 'update', and 'cancel' (case-insensitive), then a* corresponding command event is also raised (such as {@link onEditCommand OnEditCommand}).* This method should only be used by control developers.* @param TControl the sender of the event* @param TEventParameter event parameter* @return boolean whether the event bubbling should stop here.*/public function bubbleEvent($sender,$param){if($param instanceof TDataGridCommandEventParameter){$this->onItemCommand($param);$command=$param->getCommandName();if(strcasecmp($command,self::CMD_SELECT)===0){$this->setSelectedItemIndex($param->getItem()->getItemIndex());$this->onSelectedIndexChanged($param);return true;}else if(strcasecmp($command,self::CMD_EDIT)===0){$this->onEditCommand($param);return true;}else if(strcasecmp($command,self::CMD_DELETE)===0){$this->onDeleteCommand($param);return true;}else if(strcasecmp($command,self::CMD_UPDATE)===0){$this->onUpdateCommand($param);return true;}else if(strcasecmp($command,self::CMD_CANCEL)===0){$this->onCancelCommand($param);return true;}else if(strcasecmp($command,self::CMD_SORT)===0){$this->onSortCommand(new TDataGridSortCommandEventParameter($sender,$param));return true;}else if(strcasecmp($command,self::CMD_PAGE)===0){$p=$param->getCommandParameter();if(strcasecmp($p,self::CMD_PAGE_NEXT)===0)$pageIndex=$this->getCurrentPageIndex()+1;else if(strcasecmp($p,self::CMD_PAGE_PREV)===0)$pageIndex=$this->getCurrentPageIndex()-1;else$pageIndex=TPropertyValue::ensureInteger($p)-1;$this->onPageIndexChanged(new TDataGridPageChangedEventParameter($sender,$pageIndex));return true;}}return false;}/*** Raises <b>OnCancelCommand</b> event.* This method is invoked when a button control raises <b>OnCommand</b> event* with <b>cancel</b> command name.* @param TDataGridCommandEventParameter event parameter*/public function onCancelCommand($param){$this->raiseEvent('OnCancelCommand',$this,$param);}/*** Raises <b>OnDeleteCommand</b> event.* This method is invoked when a button control raises <b>OnCommand</b> event* with <b>delete</b> command name.* @param TDataGridCommandEventParameter event parameter*/public function onDeleteCommand($param){$this->raiseEvent('OnDeleteCommand',$this,$param);}/*** Raises <b>OnEditCommand</b> event.* This method is invoked when a button control raises <b>OnCommand</b> event* with <b>edit</b> command name.* @param TDataGridCommandEventParameter event parameter*/public function onEditCommand($param){$this->raiseEvent('OnEditCommand',$this,$param);}/*** Raises <b>OnItemCommand</b> event.* This method is invoked when a button control raises <b>OnCommand</b> event.* @param TDataGridCommandEventParameter event parameter*/public function onItemCommand($param){$this->raiseEvent('OnItemCommand',$this,$param);}/*** Raises <b>OnSortCommand</b> event.* This method is invoked when a button control raises <b>OnCommand</b> event* with <b>sort</b> command name.* @param TDataGridSortCommandEventParameter event parameter*/public function onSortCommand($param){$this->raiseEvent('OnSortCommand',$this,$param);}/*** Raises <b>OnUpdateCommand</b> event.* This method is invoked when a button control raises <b>OnCommand</b> event* with <b>update</b> command name.* @param TDataGridCommandEventParameter event parameter*/public function onUpdateCommand($param){$this->raiseEvent('OnUpdateCommand',$this,$param);}/*** Raises <b>OnItemCreated</b> event.* This method is invoked right after a datagrid item is created and before* added to page hierarchy.* @param TDataGridItemEventParameter event parameter*/public function onItemCreated($param){$this->raiseEvent('OnItemCreated',$this,$param);}/*** Raises <b>OnPagerCreated</b> event.* This method is invoked right after a datagrid pager is created and before* added to page hierarchy.* @param TDataGridPagerEventParameter event parameter*/public function onPagerCreated($param){$this->raiseEvent('OnPagerCreated',$this,$param);}/*** Raises <b>OnItemDataBound</b> event.* This method is invoked for each datagrid item after it performs* databinding.* @param TDataGridItemEventParameter event parameter*/public function onItemDataBound($param){$this->raiseEvent('OnItemDataBound',$this,$param);}/*** Raises <b>OnPageIndexChanged</b> event.* This method is invoked when current page is changed.* @param TDataGridPageChangedEventParameter event parameter*/public function onPageIndexChanged($param){$this->raiseEvent('OnPageIndexChanged',$this,$param);}/*** Saves item count in viewstate.* This method is invoked right before control state is to be saved.*/public function saveState(){parent::saveState();if(!$this->getEnableViewState(true))return;if($this->_items)$this->setViewState('ItemCount',$this->_items->getCount(),0);else$this->clearViewState('ItemCount');if($this->_autoColumns){$state=array();foreach($this->_autoColumns as $column)$state[]=$column->saveState();$this->setViewState('AutoColumns',$state,array());}else$this->clearViewState('AutoColumns');if($this->_columns){$state=array();foreach($this->_columns as $column)$state[]=$column->saveState();$this->setViewState('Columns',$state,array());}else$this->clearViewState('Columns');}/*** Loads item count information from viewstate.* This method is invoked right after control state is loaded.*/public function loadState(){parent::loadState();if(!$this->getEnableViewState(true))return;if(!$this->getIsDataBound()){$state=$this->getViewState('AutoColumns',array());if(!empty($state)){$this->_autoColumns=new TDataGridColumnCollection($this);foreach($state as $st){$column=new TBoundColumn;$column->loadState($st);$this->_autoColumns->add($column);}}else$this->_autoColumns=null;$state=$this->getViewState('Columns',array());if($this->_columns && $this->_columns->getCount()===count($state)){$i=0;foreach($this->_columns as $column){$column->loadState($state[$i]);$i++;}}$this->restoreGridFromViewState();}}/*** Clears up all items in the datagrid.*/public function reset(){$this->getControls()->clear();$this->getItems()->clear();$this->_header=null;$this->_footer=null;$this->_topPager=null;$this->_bottomPager=null;$this->_useEmptyTemplate=false;}/*** Restores datagrid content from viewstate.*/protected function restoreGridFromViewState(){$this->reset();$allowPaging=$this->getAllowPaging();$itemCount=$this->getViewState('ItemCount',0);$dsIndex=$this->getViewState('DataSourceIndex',0);$columns=new TList($this->getColumns());$columns->mergeWith($this->_autoColumns);$this->_allColumns=$columns;$items=$this->getItems();if($columns->getCount()){foreach($columns as $column)$column->initialize();$selectedIndex=$this->getSelectedItemIndex();$editIndex=$this->getEditItemIndex();for($index=0;$index<$itemCount;++$index){if($index===0){if($allowPaging)$this->_topPager=$this->createPager();$this->_header=$this->createItemInternal(-1,-1,TListItemType::Header,false,null,$columns);}if($index===$editIndex)$itemType=TListItemType::EditItem;else if($index===$selectedIndex)$itemType=TListItemType::SelectedItem;else if($index % 2)$itemType=TListItemType::AlternatingItem;else$itemType=TListItemType::Item;$items->add($this->createItemInternal($index,$dsIndex,$itemType,false,null,$columns));$dsIndex++;}if($index>0){$this->_footer=$this->createItemInternal(-1,-1,TListItemType::Footer,false,null,$columns);if($allowPaging)$this->_bottomPager=$this->createPager();}}if(!$dsIndex && $this->_emptyTemplate!==null){$this->_useEmptyTemplate=true;$this->_emptyTemplate->instantiateIn($this);}}/*** Performs databinding to populate datagrid items from data source.* This method is invoked by {@link dataBind()}.* You may override this function to provide your own way of data population.* @param Traversable the bound data*/protected function performDataBinding($data){$this->reset();$keys=$this->getDataKeys();$keys->clear();$keyField=$this->getDataKeyField();// get all columnsif($this->getAutoGenerateColumns()){$columns=new TList($this->getColumns());$autoColumns=$this->createAutoColumns($data);$columns->mergeWith($autoColumns);}else$columns=$this->getColumns();$this->_allColumns=$columns;$items=$this->getItems();$index=0;$allowPaging=$this->getAllowPaging() && ($data instanceof TPagedDataSource);$dsIndex=$allowPaging?$data->getFirstIndexInPage():0;$this->setViewState('DataSourceIndex',$dsIndex,0);if($columns->getCount()){foreach($columns as $column)$column->initialize();$selectedIndex=$this->getSelectedItemIndex();$editIndex=$this->getEditItemIndex();foreach($data as $key=>$row){if($keyField!=='')$keys->add($this->getDataFieldValue($row,$keyField));else$keys->add($key);if($index===0){if($allowPaging)$this->_topPager=$this->createPager();$this->_header=$this->createItemInternal(-1,-1,TListItemType::Header,true,null,$columns);}if($index===$editIndex)$itemType=TListItemType::EditItem;else if($index===$selectedIndex)$itemType=TListItemType::SelectedItem;else if($index % 2)$itemType=TListItemType::AlternatingItem;else$itemType=TListItemType::Item;$items->add($this->createItemInternal($index,$dsIndex,$itemType,true,$row,$columns));$index++;$dsIndex++;}if($index>0){$this->_footer=$this->createItemInternal(-1,-1,TListItemType::Footer,true,null,$columns);if($allowPaging)$this->_bottomPager=$this->createPager();}}$this->setViewState('ItemCount',$index,0);if(!$dsIndex && $this->_emptyTemplate!==null){$this->_useEmptyTemplate=true;$this->_emptyTemplate->instantiateIn($this);$this->dataBindChildren();}}/*** Merges consecutive cells who have the same text.* @since 3.1.1*/private function groupCells(){if(($columns=$this->_allColumns)===null)return;$items=$this->getItems();foreach($columns as $id=>$column){if(!$column->getEnableCellGrouping())continue;$prevCell=null;$prevCellText=null;foreach($items as $item){$itemType=$item->getItemType();$cell=$item->getCells()->itemAt($id);if(!$cell->getVisible())continue;if($itemType===TListItemType::Item || $itemType===TListItemType::AlternatingItem || $itemType===TListItemType::SelectedItem){if(($cellText=$this->getCellText($cell))===''){$prevCell=null;$prevCellText=null;continue;}if($prevCell===null || $prevCellText!==$cellText){$prevCell=$cell;$prevCellText=$cellText;}else{if(($rowSpan=$prevCell->getRowSpan())===0)$rowSpan=1;$prevCell->setRowSpan($rowSpan+1);$cell->setVisible(false);}}}}}private function getCellText($cell){if(($data=$cell->getText())==='' && $cell->getHasControls()){$controls=$cell->getControls();foreach($controls as $control){if($control instanceof IDataRenderer)return $control->getData();}}return $data;}/*** Creates a datagrid item instance based on the item type and index.* @param integer zero-based item index* @param TListItemType item type* @return TDataGridItem created data list item*/protected function createItem($itemIndex,$dataSourceIndex,$itemType){return new TDataGridItem($itemIndex,$dataSourceIndex,$itemType);}private function createItemInternal($itemIndex,$dataSourceIndex,$itemType,$dataBind,$dataItem,$columns){$item=$this->createItem($itemIndex,$dataSourceIndex,$itemType);$this->initializeItem($item,$columns);$param=new TDataGridItemEventParameter($item);if($dataBind){$item->setDataItem($dataItem);$this->onItemCreated($param);$this->getControls()->add($item);$item->dataBind();$this->onItemDataBound($param);}else{$this->onItemCreated($param);$this->getControls()->add($item);}return $item;}/*** Initializes a datagrid item and cells inside it* @param TDataGrid datagrid item to be initialized* @param TDataGridColumnCollection datagrid columns to be used to initialize the cells in the item*/protected function initializeItem($item,$columns){$cells=$item->getCells();$itemType=$item->getItemType();$index=0;foreach($columns as $column){if($itemType===TListItemType::Header)$cell=new TTableHeaderCell;else$cell=new TTableCell;if(($id=$column->getID())!=='')$item->registerObject($id,$cell);$cells->add($cell);$column->initializeCell($cell,$index,$itemType);$index++;}}private function createPager(){$pager=new TDataGridPager($this);$this->buildPager($pager);$this->onPagerCreated(new TDataGridPagerEventParameter($pager));$this->getControls()->add($pager);return $pager;}/*** Builds the pager content based on pager style.* @param TDataGridPager the container for the pager*/protected function buildPager($pager){switch($this->getPagerStyle()->getMode()){case TDataGridPagerMode::NextPrev:$this->buildNextPrevPager($pager);break;case TDataGridPagerMode::Numeric:$this->buildNumericPager($pager);break;}}/*** Creates a pager button.* Depending on the button type, a TLinkButton or a TButton may be created.* If it is enabled (clickable), its command name and parameter will also be set.* Derived classes may override this method to create additional types of buttons, such as TImageButton.* @param string button type, either LinkButton or PushButton* @param boolean whether the button should be enabled* @param string caption of the button* @param string CommandName corresponding to the OnCommand event of the button* @param string CommandParameter corresponding to the OnCommand event of the button* @return mixed the button instance*/protected function createPagerButton($buttonType,$enabled,$text,$commandName,$commandParameter){if($buttonType===TDataGridPagerButtonType::LinkButton){if($enabled)$button=new TLinkButton;else{$button=new TLabel;$button->setText($text);return $button;}}else{$button=new TButton;if(!$enabled)$button->setEnabled(false);}$button->setText($text);$button->setCommandName($commandName);$button->setCommandParameter($commandParameter);$button->setCausesValidation(false);return $button;}/*** Builds a next-prev pager* @param TDataGridPager the container for the pager*/protected function buildNextPrevPager($pager){$style=$this->getPagerStyle();$buttonType=$style->getButtonType();$controls=$pager->getControls();$currentPageIndex=$this->getCurrentPageIndex();if($currentPageIndex===0){$label=$this->createPagerButton($buttonType,false,$style->getPrevPageText(),'','');$controls->add($label);}else{$button=$this->createPagerButton($buttonType,true,$style->getPrevPageText(),self::CMD_PAGE,self::CMD_PAGE_PREV);$controls->add($button);}$controls->add("\n");if($currentPageIndex===$this->getPageCount()-1){$label=$this->createPagerButton($buttonType,false,$style->getNextPageText(),'','');$controls->add($label);}else{$button=$this->createPagerButton($buttonType,true,$style->getNextPageText(),self::CMD_PAGE,self::CMD_PAGE_NEXT);$controls->add($button);}}/*** Builds a numeric pager* @param TDataGridPager the container for the pager*/protected function buildNumericPager($pager){$style=$this->getPagerStyle();$buttonType=$style->getButtonType();$controls=$pager->getControls();$pageCount=$this->getPageCount();$pageIndex=$this->getCurrentPageIndex()+1;$maxButtonCount=$style->getPageButtonCount();$buttonCount=$maxButtonCount>$pageCount?$pageCount:$maxButtonCount;$startPageIndex=1;$endPageIndex=$buttonCount;if($pageIndex>$endPageIndex){$startPageIndex=((int)(($pageIndex-1)/$maxButtonCount))*$maxButtonCount+1;if(($endPageIndex=$startPageIndex+$maxButtonCount-1)>$pageCount)$endPageIndex=$pageCount;if($endPageIndex-$startPageIndex+1<$maxButtonCount){if(($startPageIndex=$endPageIndex-$maxButtonCount+1)<1)$startPageIndex=1;}}if($startPageIndex>1){$prevPageIndex=$startPageIndex-1;$button=$this->createPagerButton($buttonType,true,$style->getPrevPageText(),self::CMD_PAGE,"$prevPageIndex");$controls->add($button);$controls->add("\n");}for($i=$startPageIndex;$i<=$endPageIndex;++$i){if($i===$pageIndex){$label=$this->createPagerButton($buttonType,false,"$i",'','');$controls->add($label);}else{$button=$this->createPagerButton($buttonType,true,"$i",self::CMD_PAGE,"$i");$controls->add($button);}if($i<$endPageIndex)$controls->add("\n");}if($pageCount>$endPageIndex){$controls->add("\n");$nextPageIndex=$endPageIndex+1;$button=$this->createPagerButton($buttonType,true,$style->getNextPageText(),self::CMD_PAGE,"$nextPageIndex");$controls->add($button);}}/*** Automatically generates datagrid columns based on datasource schema* @param Traversable data source bound to the datagrid* @return TDataGridColumnCollection*/protected function createAutoColumns($dataSource){if(!$dataSource)return null;$autoColumns=$this->getAutoColumns();$autoColumns->clear();foreach($dataSource as $row){foreach($row as $key=>$value){$column=new TBoundColumn;if(is_string($key)){$column->setHeaderText($key);$column->setDataField($key);$column->setSortExpression($key);$autoColumns->add($column);}else{$column->setHeaderText(TListItemType::Item);$column->setDataField($key);$column->setSortExpression(TListItemType::Item);$autoColumns->add($column);}}break;}return $autoColumns;}/*** Applies styles to items, header, footer and separators.* Item styles are applied in a hierarchical way. Style in higher hierarchy* will inherit from styles in lower hierarchy.* Starting from the lowest hierarchy, the item styles include* item's own style, {@link getItemStyle ItemStyle}, {@link getAlternatingItemStyle AlternatingItemStyle},* {@link getSelectedItemStyle SelectedItemStyle}, and {@link getEditItemStyle EditItemStyle}.* Therefore, if background color is set as red in {@link getItemStyle ItemStyle},* {@link getEditItemStyle EditItemStyle} will also have red background color* unless it is set to a different value explicitly.*/protected function applyItemStyles(){$itemStyle=$this->getViewState('ItemStyle',null);$alternatingItemStyle=$this->getViewState('AlternatingItemStyle',null);if($itemStyle!==null){if($alternatingItemStyle===null)$alternatingItemStyle=$itemStyle;else$alternatingItemStyle->mergeWith($itemStyle);}$selectedItemStyle=$this->getViewState('SelectedItemStyle',null);$editItemStyle=$this->getViewState('EditItemStyle',null);if($selectedItemStyle!==null){if($editItemStyle===null)$editItemStyle=$selectedItemStyle;else$editItemStyle->mergeWith($selectedItemStyle);}$headerStyle=$this->getViewState('HeaderStyle',null);$footerStyle=$this->getViewState('FooterStyle',null);$pagerStyle=$this->getViewState('PagerStyle',null);$separatorStyle=$this->getViewState('SeparatorStyle',null);foreach($this->getControls() as $index=>$item){if(!($item instanceof TDataGridItem) && !($item instanceof TDataGridPager))continue;$itemType=$item->getItemType();switch($itemType){case TListItemType::Header:if($headerStyle)$item->getStyle()->mergeWith($headerStyle);if(!$this->getShowHeader())$item->setVisible(false);break;case TListItemType::Footer:if($footerStyle)$item->getStyle()->mergeWith($footerStyle);if(!$this->getShowFooter())$item->setVisible(false);break;case TListItemType::Separator:if($separatorStyle)$item->getStyle()->mergeWith($separatorStyle);break;case TListItemType::Item:if($itemStyle)$item->getStyle()->mergeWith($itemStyle);break;case TListItemType::AlternatingItem:if($alternatingItemStyle)$item->getStyle()->mergeWith($alternatingItemStyle);break;case TListItemType::SelectedItem:if($selectedItemStyle)$item->getStyle()->mergeWith($selectedItemStyle);if($index % 2==1){if($itemStyle)$item->getStyle()->mergeWith($itemStyle);}else{if($alternatingItemStyle)$item->getStyle()->mergeWith($alternatingItemStyle);}break;case TListItemType::EditItem:if($editItemStyle)$item->getStyle()->mergeWith($editItemStyle);if($index % 2==1){if($itemStyle)$item->getStyle()->mergeWith($itemStyle);}else{if($alternatingItemStyle)$item->getStyle()->mergeWith($alternatingItemStyle);}break;case TListItemType::Pager:if($pagerStyle){$item->getStyle()->mergeWith($pagerStyle);if($index===0){if($pagerStyle->getPosition()===TDataGridPagerPosition::Bottom || !$pagerStyle->getVisible())$item->setVisible(false);}else{if($pagerStyle->getPosition()===TDataGridPagerPosition::Top || !$pagerStyle->getVisible())$item->setVisible(false);}}break;default:break;}if($this->_columns && $itemType!==TListItemType::Pager){$n=$this->_columns->getCount();$cells=$item->getCells();for($i=0;$i<$n;++$i){$cell=$cells->itemAt($i);$column=$this->_columns->itemAt($i);if(!$column->getVisible())$cell->setVisible(false);else{if($itemType===TListItemType::Header)$style=$column->getHeaderStyle(false);else if($itemType===TListItemType::Footer)$style=$column->getFooterStyle(false);else$style=$column->getItemStyle(false);if($style!==null)$cell->getStyle()->mergeWith($style);}}}}}/*** Renders the openning tag for the datagrid control which will render table caption if present.* @param THtmlWriter the writer used for the rendering purpose*/public function renderBeginTag($writer){parent::renderBeginTag($writer);if(($caption=$this->getCaption())!==''){if(($align=$this->getCaptionAlign())!==TTableCaptionAlign::NotSet)$writer->addAttribute('align',strtolower($align));$writer->renderBeginTag('caption');$writer->write($caption);$writer->renderEndTag();}}/*** Renders the datagrid.* @param THtmlWriter writer for the rendering purpose*/public function render($writer){if($this->getHasControls()){$this->groupCells();if($this->_useEmptyTemplate){$control=new TWebControl;$control->setID($this->getClientID());$control->copyBaseAttributes($this);if($this->getHasStyle())$control->getStyle()->copyFrom($this->getStyle());$control->renderBeginTag($writer);$this->renderContents($writer);$control->renderEndTag($writer);}else if($this->getViewState('ItemCount',0)>0){$this->applyItemStyles();if($this->_topPager){$this->_topPager->renderControl($writer);$writer->writeLine();}$this->renderTable($writer);if($this->_bottomPager){$writer->writeLine();$this->_bottomPager->renderControl($writer);}}}}/*** Renders the tabular data.* @param THtmlWriter writer*/protected function renderTable($writer){$this->renderBeginTag($writer);if($this->_header && $this->_header->getVisible()){$writer->writeLine();if($style=$this->getViewState('TableHeadStyle',null))$style->addAttributesToRender($writer);$writer->renderBeginTag('thead');$this->_header->render($writer);$writer->renderEndTag();}$writer->writeLine();if($style=$this->getViewState('TableBodyStyle',null))$style->addAttributesToRender($writer);$writer->renderBeginTag('tbody');foreach($this->getItems() as $item)$item->renderControl($writer);$writer->renderEndTag();if($this->_footer && $this->_footer->getVisible()){$writer->writeLine();if($style=$this->getViewState('TableFootStyle',null))$style->addAttributesToRender($writer);$writer->renderBeginTag('tfoot');$this->_footer->render($writer);$writer->renderEndTag();}$writer->writeLine();$this->renderEndTag($writer);}}/*** TDataGridItemEventParameter class** TDataGridItemEventParameter encapsulates the parameter data for* {@link TDataGrid::onItemCreated OnItemCreated} event of {@link TDataGrid} controls.* The {@link getItem Item} property indicates the datagrid item related with the event.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0*/class TDataGridItemEventParameter extends TEventParameter{/*** The TDataGridItem control responsible for the event.* @var TDataGridItem*/private $_item=null;/*** Constructor.* @param TDataGridItem datagrid item related with the corresponding event*/public function __construct(TDataGridItem $item){$this->_item=$item;}/*** @return TDataGridItem datagrid item related with the corresponding event*/public function getItem(){return $this->_item;}}/*** TDataGridPagerEventParameter class** TDataGridPagerEventParameter encapsulates the parameter data for* {@link TDataGrid::onPagerCreated OnPagerCreated} event of {@link TDataGrid} controls.* The {@link getPager Pager} property indicates the datagrid pager related with the event.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0*/class TDataGridPagerEventParameter extends TEventParameter{/*** The TDataGridPager control responsible for the event.* @var TDataGridPager*/private $_pager=null;/*** Constructor.* @param TDataGridPager datagrid pager related with the corresponding event*/public function __construct(TDataGridPager $pager){$this->_pager=$pager;}/*** @return TDataGridPager datagrid pager related with the corresponding event*/public function getPager(){return $this->_pager;}}/*** TDataGridCommandEventParameter class** TDataGridCommandEventParameter encapsulates the parameter data for* {@link TDataGrid::onItemCommand ItemCommand} event of {@link TDataGrid} controls.** The {@link getItem Item} property indicates the datagrid item related with the event.* The {@link getCommandSource CommandSource} refers to the control that originally* raises the Command event.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0*/class TDataGridCommandEventParameter extends TCommandEventParameter{/*** @var TDataGridItem the TDataGridItem control responsible for the event.*/private $_item=null;/*** @var TControl the control originally raises the <b>Command</b> event.*/private $_source=null;/*** Constructor.* @param TDataGridItem datagrid item responsible for the event* @param TControl original event sender* @param TCommandEventParameter original event parameter*/public function __construct($item,$source,TCommandEventParameter $param){$this->_item=$item;$this->_source=$source;parent::__construct($param->getCommandName(),$param->getCommandParameter());}/*** @return TDataGridItem the TDataGridItem control responsible for the event.*/public function getItem(){return $this->_item;}/*** @return TControl the control originally raises the <b>Command</b> event.*/public function getCommandSource(){return $this->_source;}}/*** TDataGridSortCommandEventParameter class** TDataGridSortCommandEventParameter encapsulates the parameter data for* {@link TDataGrid::onSortCommand SortCommand} event of {@link TDataGrid} controls.** The {@link getCommandSource CommandSource} property refers to the control* that originally raises the OnCommand event, while {@link getSortExpression SortExpression}* gives the sort expression carried with the sort command.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0*/class TDataGridSortCommandEventParameter extends TEventParameter{/*** @var string sort expression*/private $_sortExpression='';/*** @var TControl original event sender*/private $_source=null;/*** Constructor.* @param TControl the control originally raises the <b>OnCommand</b> event.* @param TDataGridCommandEventParameter command event parameter*/public function __construct($source,TDataGridCommandEventParameter $param){$this->_source=$source;$this->_sortExpression=$param->getCommandParameter();}/*** @return TControl the control originally raises the <b>OnCommand</b> event.*/public function getCommandSource(){return $this->_source;}/*** @return string sort expression*/public function getSortExpression(){return $this->_sortExpression;}}/*** TDataGridPageChangedEventParameter class** TDataGridPageChangedEventParameter encapsulates the parameter data for* {@link TDataGrid::onPageIndexChanged PageIndexChanged} event of {@link TDataGrid} controls.** The {@link getCommandSource CommandSource} property refers to the control* that originally raises the OnCommand event, while {@link getNewPageIndex NewPageIndex}* returns the new page index carried with the page command.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0*/class TDataGridPageChangedEventParameter extends TEventParameter{/*** @var integer new page index*/private $_newIndex;/*** @var TControl original event sender*/private $_source=null;/*** Constructor.* @param TControl the control originally raises the <b>OnCommand</b> event.* @param integer new page index*/public function __construct($source,$newPageIndex){$this->_source=$source;$this->_newIndex=$newPageIndex;}/*** @return TControl the control originally raises the <b>OnCommand</b> event.*/public function getCommandSource(){return $this->_source;}/*** @return integer new page index*/public function getNewPageIndex(){return $this->_newIndex;}}/*** TDataGridItem class** A TDataGridItem control represents an item in the {@link TDataGrid} control,* such as heading section, footer section, or a data item.* The index and data value of the item can be accessed via {@link getItemIndex ItemIndex}>* and {@link getDataItem DataItem} properties, respectively. The type of the item* is given by {@link getItemType ItemType} property. Property {@link getDataSourceIndex DataSourceIndex}* gives the index of the item from the bound data source.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0*/class TDataGridItem extends TTableRow implements INamingContainer{/*** @var integer index of the data item in the Items collection of datagrid*/private $_itemIndex='';/*** @var integer index of the item from the bound data source*/private $_dataSourceIndex=0;/*** type of the TDataGridItem* @var string*/private $_itemType='';/*** value of the data item* @var mixed*/private $_data=null;/*** Constructor.* @param integer zero-based index of the item in the item collection of datagrid* @param TListItemType item type*/public function __construct($itemIndex,$dataSourceIndex,$itemType){$this->_itemIndex=$itemIndex;$this->_dataSourceIndex=$dataSourceIndex;$this->setItemType($itemType);if($itemType===TListItemType::Header)$this->setTableSection(TTableRowSection::Header);else if($itemType===TListItemType::Footer)$this->setTableSection(TTableRowSection::Footer);}/*** @return TListItemType item type.*/public function getItemType(){return $this->_itemType;}/*** @param TListItemType item type*/public function setItemType($value){$this->_itemType=TPropertyValue::ensureEnum($value,'TListItemType');}/*** @return integer zero-based index of the item in the item collection of datagrid*/public function getItemIndex(){return $this->_itemIndex;}/*** @return integer the index of the datagrid item from the bound data source*/public function getDataSourceIndex(){return $this->_dataSourceIndex;}/*** @return mixed data associated with the item* @since 3.1.0*/public function getData(){return $this->_data;}/*** @param mixed data to be associated with the item* @since 3.1.0*/public function setData($value){$this->_data=$value;}/*** This property is deprecated since v3.1.0.* @return mixed data associated with the item* @deprecated deprecated since v3.1.0. Use {@link getData} instead.*/public function getDataItem(){return $this->getData();}/*** This property is deprecated since v3.1.0.* @param mixed data to be associated with the item* @deprecated deprecated since version 3.1.0. Use {@link setData} instead.*/public function setDataItem($value){return $this->setData($value);}/*** This method overrides parent's implementation by wrapping event parameter* for <b>OnCommand</b> event with item information.* @param TControl the sender of the event* @param TEventParameter event parameter* @return boolean whether the event bubbling should stop here.*/public function bubbleEvent($sender,$param){if($param instanceof TCommandEventParameter){$this->raiseBubbleEvent($this,new TDataGridCommandEventParameter($this,$sender,$param));return true;}elsereturn false;}}/*** TDataGridPager class.** TDataGridPager represents a datagrid pager.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0*/class TDataGridPager extends TPanel implements INamingContainer{private $_dataGrid;/*** Constructor.* @param TDataGrid datagrid object*/public function __construct($dataGrid){$this->_dataGrid=$dataGrid;}/*** This method overrides parent's implementation by wrapping event parameter* for <b>OnCommand</b> event with item information.* @param TControl the sender of the event* @param TEventParameter event parameter* @return boolean whether the event bubbling should stop here.*/public function bubbleEvent($sender,$param){if($param instanceof TCommandEventParameter){$this->raiseBubbleEvent($this,new TDataGridCommandEventParameter($this,$sender,$param));return true;}elsereturn false;}/*** @return TDataGrid the datagrid owning this pager*/public function getDataGrid(){return $this->_dataGrid;}/*** @return string item type.*/public function getItemType(){return TListItemType::Pager;}}/*** TDataGridItemCollection class.** TDataGridItemCollection represents a collection of data grid items.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0*/class TDataGridItemCollection extends TList{/*** Inserts an item at the specified position.* This overrides the parent implementation by inserting only TDataGridItem.* @param integer the speicified position.* @param mixed new item* @throws TInvalidDataTypeException if the item to be inserted is not a TDataGridItem.*/public function insertAt($index,$item){if($item instanceof TDataGridItem)parent::insertAt($index,$item);elsethrow new TInvalidDataTypeException('datagriditemcollection_datagriditem_required');}}/*** TDataGridColumnCollection class.** TDataGridColumnCollection represents a collection of data grid columns.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0*/class TDataGridColumnCollection extends TList{/*** the control that owns this collection.* @var TControl*/private $_o;/*** Constructor.* @param TDataGrid the control that owns this collection.*/public function __construct(TDataGrid $owner){$this->_o=$owner;}/*** @return TDataGrid the control that owns this collection.*/protected function getOwner(){return $this->_o;}/*** Inserts an item at the specified position.* This overrides the parent implementation by inserting only TDataGridColumn.* @param integer the speicified position.* @param mixed new item* @throws TInvalidDataTypeException if the item to be inserted is not a TDataGridColumn.*/public function insertAt($index,$item){if($item instanceof TDataGridColumn){$item->setOwner($this->_o);parent::insertAt($index,$item);}elsethrow new TInvalidDataTypeException('datagridcolumncollection_datagridcolumn_required');}}/*** TDataGridPagerMode class.* TDataGridPagerMode defines the enumerable type for the possible modes that a datagrid pager can take.** The following enumerable values are defined:* - NextPrev: pager buttons are displayed as next and previous pages* - Numeric: pager buttons are displayed as numeric page numbers** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0.4*/class TDataGridPagerMode extends TEnumerable{const NextPrev='NextPrev';const Numeric='Numeric';}/*** TDataGridPagerButtonType class.* TDataGridPagerButtonType defines the enumerable type for the possible types of datagrid pager buttons.** The following enumerable values are defined:* - LinkButton: link buttons* - PushButton: form submit buttons** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0.4*/class TDataGridPagerButtonType extends TEnumerable{const LinkButton='LinkButton';const PushButton='PushButton';}/*** TDataGridPagerPosition class.* TDataGridPagerPosition defines the enumerable type for the possible positions that a datagrid pager can be located at.** The following enumerable values are defined:* - Bottom: pager appears only at the bottom of the data grid.* - Top: pager appears only at the top of the data grid.* - TopAndBottom: pager appears on both top and bottom of the data grid.** @author Qiang Xue <qiang.xue@gmail.com>* @version $Id: TDataGrid.php 2541 2008-10-21 15:05:13Z qiang.xue $* @package System.Web.UI.WebControls* @since 3.0.4*/class TDataGridPagerPosition extends TEnumerable{const Bottom='Bottom';const Top='Top';const TopAndBottom='TopAndBottom';}