From 0aaa8b5ef02479653c0a532d9249b423ef34c7ca Mon Sep 17 00:00:00 2001
From: xue <>
Date: Mon, 5 Feb 2007 02:24:34 +0000
Subject: Added IStyleable and fixed style rendering issue about TDataList.

---
 framework/Web/UI/WebControls/TDataList.php         | 347 ++++-----------------
 .../Web/UI/WebControls/TDataListItemRenderer.php   | 241 ++++++++++++++
 framework/Web/UI/WebControls/TRepeater.php         | 109 -------
 .../Web/UI/WebControls/TRepeaterItemRenderer.php   | 123 ++++++++
 framework/Web/UI/WebControls/TWebControl.php       |  10 +-
 5 files changed, 428 insertions(+), 402 deletions(-)
 create mode 100644 framework/Web/UI/WebControls/TDataListItemRenderer.php
 create mode 100644 framework/Web/UI/WebControls/TRepeaterItemRenderer.php

(limited to 'framework/Web')

diff --git a/framework/Web/UI/WebControls/TDataList.php b/framework/Web/UI/WebControls/TDataList.php
index 0fee2243..6538d7fa 100644
--- a/framework/Web/UI/WebControls/TDataList.php
+++ b/framework/Web/UI/WebControls/TDataList.php
@@ -675,13 +675,13 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
 			if($current>=0 && $current<$itemCount)
 			{
 				$item=$items->itemAt($current);
-				if($item->getItemType()!==TListItemType::EditItem)
+				if(($item instanceof IItemDataRenderer) && $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)
+				if(($item instanceof IItemDataRenderer) && $item->getItemType()!==TListItemType::EditItem)
 					$item->setItemType(TListItemType::SelectedItem);
 			}
 		}
@@ -906,7 +906,8 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
 			$command=$param->getCommandName();
 			if(strcasecmp($command,self::CMD_SELECT)===0)
 			{
-				$this->setSelectedItemIndex($param->getItem()->getItemIndex());
+				if(($item=$param->getItem()) instanceof IItemDataRenderer)
+					$this->setSelectedItemIndex($item->getItemIndex());
 				$this->onSelectedIndexChanged($param);
 				return true;
 			}
@@ -1022,21 +1023,21 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
 	/**
 	 * Returns a value indicating whether this control contains header item.
 	 * This method is required by {@link IRepeatInfoUser} interface.
-	 * @return boolean always false.
+	 * @return boolean whether the datalist has header
 	 */
 	public function getHasHeader()
 	{
-		return ($this->getShowHeader() && $this->_headerTemplate!==null);
+		return ($this->getShowHeader() && ($this->_headerTemplate!==null || $this->getHeaderRenderer()!==''));
 	}
 
 	/**
 	 * Returns a value indicating whether this control contains footer item.
 	 * This method is required by {@link IRepeatInfoUser} interface.
-	 * @return boolean always false.
+	 * @return boolean whether the datalist has footer
 	 */
 	public function getHasFooter()
 	{
-		return ($this->getShowFooter() && $this->_footerTemplate!==null);
+		return ($this->getShowFooter() && ($this->_footerTemplate!==null || $this->getFooterRenderer()!==''));
 	}
 
 	/**
@@ -1046,7 +1047,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
 	 */
 	public function getHasSeparators()
 	{
-		return $this->_separatorTemplate!==null;
+		return $this->_separatorTemplate!==null || $this->getSeparatorRenderer()!=='';
 	}
 
 	/**
@@ -1058,8 +1059,12 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
 	 */
 	public function generateItemStyle($itemType,$index)
 	{
-		if(($item=$this->getItem($itemType,$index))!==null && $item->getHasStyle())
-			return $item->getStyle();
+		if(($item=$this->getItem($itemType,$index))!==null && ($item instanceof IStyleable) && $item->getHasStyle())
+		{
+			$style=$item->getStyle();
+			$item->clearStyle();
+			return $style;
+		}
 		else
 			return null;
 	}
@@ -1076,10 +1081,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
 	{
 		$item=$this->getItem($itemType,$index);
 		$layout=$repeatInfo->getRepeatLayout();
-		if($layout==='Table' || $layout==='Raw')
-			$item->renderContents($writer);
-		else
-			$item->renderControl($writer);
+		$item->renderControl($writer);
 	}
 
 	/**
@@ -1102,7 +1104,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
 				return $this->getControls()->itemAt($this->getControls()->getCount()-1);
 			case TListItemType::Separator:
 				$i=$index+$index+1;
-				if($this->_headerTemplate!==null)
+				if($this->_headerTemplate!==null || $this->getHeaderRenderer()!=='')
 					$i++;
 				return $this->getControls()->itemAt($i);
 		}
@@ -1284,66 +1286,47 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
 				$editItemStyle->mergeWith($selectedItemStyle);
 		}
 
-		$headerStyle=$this->getViewState('HeaderStyle',null);
-		$footerStyle=$this->getViewState('FooterStyle',null);
-		$separatorStyle=$this->getViewState('SeparatorStyle',null);
+		// apply header style if any
+		if($this->_header!==null && $this->_header instanceof IStyleable)
+		{
+			if($headerStyle=$this->getViewState('HeaderStyle',null))
+				$this->_header->getStyle()->mergeWith($headerStyle);
+		}
 
-		foreach($this->getControls() as $index=>$item)
+		// apply footer style if any
+		if($this->_footer!==null && $this->_footer instanceof IStyleable)
 		{
-			if(!($item instanceof IItemDataRenderer) || !$item->hasProperty('Style'))
-				continue;
-			switch($item->getItemType())
+			if($footerStyle=$this->getViewState('FooterStyle',null))
+				$this->_footer->getStyle()->mergeWith($headerStyle);
+		}
+
+		$selectedIndex=$this->getSelectedItemIndex();
+		$editIndex=$this->getEditItemIndex();
+
+		// apply item styles if any
+		foreach($this->getItems() as $index=>$item)
+		{
+			if($index===$editIndex)
+				$style=$editItemStyle;
+			else if($index===$selectedIndex)
+				$style=$selectedItemStyle;
+			else if($index%2===0)
+				$style=$itemStyle;
+			else
+				$style=$alternatingItemStyle;
+			if($style && $item instanceof IStyleable)
+				$item->getStyle()->mergeWith($style);
+		}
+
+		// apply separator style if any
+		if(($separatorStyle=$this->getViewState('SeparatorStyle',null))!==null && $this->getHasSeparators())
+		{
+			$controls=$this->getControls();
+			$count=$controls->getCount();
+			for($i=$this->_header?2:1;$i<$count;$i+=2)
 			{
-				case TListItemType::Header:
-					if($headerStyle)
-						$item->getStyle()->mergeWith($headerStyle);
-					break;
-				case TListItemType::Footer:
-					if($footerStyle)
-						$item->getStyle()->mergeWith($footerStyle);
-					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;
-				default:
-					break;
+				if(($separator=$controls->itemAt($i)) instanceof IStyleable)
+					$separator->getStyle()->mergeWith($separatorStyle);
 			}
 		}
 	}
@@ -1708,226 +1691,6 @@ class TDataListItem extends TWebControl implements INamingContainer, IItemDataRe
 	}
 }
 
-
-
-/**
- * TDataListItemRenderer class
- *
- * TDataListItemRenderer can be used as a convenient base class to
- * define an item renderer class for {@link TDataList}.
- *
- * Because TDataListItemRenderer extends from {@link TTemplateControl}, derived child classes
- * can have templates to define their presentational layout.
- *
- * TDataListItemRenderer implements {@link IItemDataRenderer} interface,
- * which enables the following properties that are related with data-bound controls:
- * - {@link getItemIndex ItemIndex}: zero-based index of this control in the datalist item collection.
- * - {@link getItemType ItemType}: item type of this control, such as TListItemType::AlternatingItem
- * - {@link getData Data}: data associated with this control
-
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.1.0
- */
-class TDataListItemRenderer extends TTemplateControl implements IItemDataRenderer
-{
-	/**
-	 * index of the data item in the Items collection of TDataList
-	 * @var integer
-	 */
-	private $_itemIndex;
-	/**
-	 * type of the TDataListItem
-	 * @var TListItemType
-	 */
-	private $_itemType;
-	/**
-	 * value of the data associated with this item
-	 * @var mixed
-	 */
-	private $_data;
-
-	/**
-	 * @return boolean whether the control has defined any style information
-	 */
-	public function getHasStyle()
-	{
-		return $this->getViewState('Style',null)!==null;
-	}
-
-	/**
-	 * Creates a style object to be used by the control.
-	 * This method may be overriden by controls to provide customized style.
-	 * @return TStyle
-	 */
-	protected function createStyle()
-	{
-		return new TStyle;
-	}
-
-	/**
-	 * @return TStyle the object representing the css style of the control
-	 */
-	public function getStyle()
-	{
-		if($style=$this->getViewState('Style',null))
-			return $style;
-		else
-		{
-			$style=$this->createStyle();
-			$this->setViewState('Style',$style,null);
-			return $style;
-		}
-	}
-
-	/**
-	 * @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 datalist
-	 */
-	public function getItemIndex()
-	{
-		return $this->_itemIndex;
-	}
-
-	/**
-	 * Sets the zero-based index for the item.
-	 * If the item is not in the item collection (e.g. it is a header item), -1 should be used.
-	 * @param integer zero-based index of the item.
-	 */
-	public function setItemIndex($value)
-	{
-		$this->_itemIndex=TPropertyValue::ensureInteger($value);
-	}
-
-	/**
-	 * @return mixed data associated with the item
-	 */
-	public function getData()
-	{
-		return $this->_data;
-	}
-
-	/**
-	 * @param mixed data to be associated with the item
-	 */
-	public function setData($value)
-	{
-		$this->_data=$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 TDataListCommandEventParameter($this,$sender,$param));
-			return true;
-		}
-		else
-			return false;
-	}
-
-	/**
-	 * Returns the tag name used for this control.
-	 * By default, the tag name is 'span'.
-	 * You can override this method to provide customized tag names.
-	 * If the tag name is empty, the opening and closing tag will NOT be rendered.
-	 * @return string tag name of the control to be rendered
-	 */
-	protected function getTagName()
-	{
-		return 'span';
-	}
-
-	/**
-	 * Adds attribute name-value pairs to renderer.
-	 * By default, this method renders the style string.
-	 * The method can be overriden to provide customized attribute rendering.
-	 * @param THtmlWriter the writer used for the rendering purpose
-	 */
-	protected function addAttributesToRender($writer)
-	{
-		if($style=$this->getViewState('Style',null))
-			$style->addAttributesToRender($writer);
-	}
-
-	/**
-	 * Renders the control.
-	 * This method overrides the parent implementation by replacing it with
-	 * the following sequence:
-	 * - {@link renderBeginTag}
-	 * - {@link renderContents}
-	 * - {@link renderEndTag}
-	 * If the {@link getTagName TagName} is empty, only {@link renderContents} is invoked.
-	 * @param THtmlWriter the writer used for the rendering purpose
-	 */
-	public function render($writer)
-	{
-		if($this->getTagName()!=='')
-		{
-			$this->renderBeginTag($writer);
-			$this->renderContents($writer);
-			$this->renderEndTag($writer);
-		}
-		else
-			$this->renderContents();
-	}
-
-	/**
-	 * Renders the openning tag for the control (including attributes)
-	 * This method is invoked when {@link getTagName TagName} is not empty.
-	 * @param THtmlWriter the writer used for the rendering purpose
-	 */
-	public function renderBeginTag($writer)
-	{
-		$this->addAttributesToRender($writer);
-		$writer->renderBeginTag($this->getTagName());
-	}
-
-	/**
-	 * Renders the body content enclosed between the control tag.
-	 * By default, child controls and text strings will be rendered.
-	 * You can override this method to provide customized content rendering.
-	 * @param THtmlWriter the writer used for the rendering purpose
-	 */
-	public function renderContents($writer)
-	{
-		parent::renderChildren($writer);
-	}
-
-	/**
-	 * Renders the closing tag for the control
-	 * This method is invoked when {@link getTagName TagName} is not empty.
-	 * @param THtmlWriter the writer used for the rendering purpose
-	 */
-	public function renderEndTag($writer)
-	{
-		$writer->renderEndTag();
-	}
-}
-
 /**
  * TDataListItemCollection class.
  *
diff --git a/framework/Web/UI/WebControls/TDataListItemRenderer.php b/framework/Web/UI/WebControls/TDataListItemRenderer.php
new file mode 100644
index 00000000..82f466e9
--- /dev/null
+++ b/framework/Web/UI/WebControls/TDataListItemRenderer.php
@@ -0,0 +1,241 @@
+<?php
+/**
+ * TDataListItemRenderer class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2007 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @package System.Web.UI.WebControls
+ */
+
+Prado::using('System.Web.UI.WebControls.TDataList');
+
+/**
+ * TDataListItemRenderer class
+ *
+ * TDataListItemRenderer can be used as a convenient base class to
+ * define an item renderer class for {@link TDataList}.
+ *
+ * Because TDataListItemRenderer extends from {@link TTemplateControl}, derived child classes
+ * can have templates to define their presentational layout.
+ *
+ * TDataListItemRenderer implements {@link IItemDataRenderer} interface,
+ * which enables the following properties that are related with data-bound controls:
+ * - {@link getItemIndex ItemIndex}: zero-based index of this control in the datalist item collection.
+ * - {@link getItemType ItemType}: item type of this control, such as TListItemType::AlternatingItem
+ * - {@link getData Data}: data associated with this control
+
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System.Web.UI.WebControls
+ * @since 3.1.0
+ */
+class TDataListItemRenderer extends TTemplateControl implements IItemDataRenderer, IStyleable
+{
+	/**
+	 * index of the data item in the Items collection of TDataList
+	 * @var integer
+	 */
+	private $_itemIndex;
+	/**
+	 * type of the TDataListItem
+	 * @var TListItemType
+	 */
+	private $_itemType;
+	/**
+	 * value of the data associated with this item
+	 * @var mixed
+	 */
+	private $_data;
+
+	/**
+	 * Creates a style object to be used by the control.
+	 * This method may be overriden by controls to provide customized style.
+	 * @return TStyle
+	 */
+	protected function createStyle()
+	{
+		return new TTableItemStyle;
+	}
+
+	/**
+	 * @return boolean whether the control has defined any style information
+	 */
+	public function getHasStyle()
+	{
+		return $this->getViewState('Style',null)!==null;
+	}
+
+	/**
+	 * @return TStyle the object representing the css style of the control
+	 */
+	public function getStyle()
+	{
+		if($style=$this->getViewState('Style',null))
+			return $style;
+		else
+		{
+			$style=$this->createStyle();
+			$this->setViewState('Style',$style,null);
+			return $style;
+		}
+	}
+
+	/**
+	 * Removes all style data.
+	 */
+	public function clearStyle()
+	{
+		$this->clearViewState('Style');
+	}
+
+	/**
+	 * @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 datalist
+	 */
+	public function getItemIndex()
+	{
+		return $this->_itemIndex;
+	}
+
+	/**
+	 * Sets the zero-based index for the item.
+	 * If the item is not in the item collection (e.g. it is a header item), -1 should be used.
+	 * @param integer zero-based index of the item.
+	 */
+	public function setItemIndex($value)
+	{
+		$this->_itemIndex=TPropertyValue::ensureInteger($value);
+	}
+
+	/**
+	 * @return mixed data associated with the item
+	 */
+	public function getData()
+	{
+		return $this->_data;
+	}
+
+	/**
+	 * @param mixed data to be associated with the item
+	 */
+	public function setData($value)
+	{
+		$this->_data=$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 TDataListCommandEventParameter($this,$sender,$param));
+			return true;
+		}
+		else
+			return false;
+	}
+
+	/**
+	 * Returns the tag name used for this control.
+	 * By default, the tag name is 'span'.
+	 * You can override this method to provide customized tag names.
+	 * If the tag name is empty, the opening and closing tag will NOT be rendered.
+	 * @return string tag name of the control to be rendered
+	 */
+	protected function getTagName()
+	{
+		return 'span';
+	}
+
+	/**
+	 * Adds attribute name-value pairs to renderer.
+	 * By default, this method renders the style string.
+	 * The method can be overriden to provide customized attribute rendering.
+	 * @param THtmlWriter the writer used for the rendering purpose
+	 */
+	protected function addAttributesToRender($writer)
+	{
+		if($style=$this->getViewState('Style',null))
+			$style->addAttributesToRender($writer);
+	}
+
+	/**
+	 * Renders the control.
+	 * This method overrides the parent implementation by replacing it with
+	 * the following sequence:
+	 * - {@link renderBeginTag}
+	 * - {@link renderContents}
+	 * - {@link renderEndTag}
+	 * If the {@link getTagName TagName} is empty, only {@link renderContents} is invoked.
+	 * @param THtmlWriter the writer used for the rendering purpose
+	 */
+	public function render($writer)
+	{
+		if($this->getTagName()!=='')
+		{
+			$this->renderBeginTag($writer);
+			$this->renderContents($writer);
+			$this->renderEndTag($writer);
+		}
+		else
+			$this->renderContents();
+	}
+
+	/**
+	 * Renders the openning tag for the control (including attributes)
+	 * This method is invoked when {@link getTagName TagName} is not empty.
+	 * @param THtmlWriter the writer used for the rendering purpose
+	 */
+	public function renderBeginTag($writer)
+	{
+		$this->addAttributesToRender($writer);
+		$writer->renderBeginTag($this->getTagName());
+	}
+
+	/**
+	 * Renders the body content enclosed between the control tag.
+	 * By default, child controls and text strings will be rendered.
+	 * You can override this method to provide customized content rendering.
+	 * @param THtmlWriter the writer used for the rendering purpose
+	 */
+	public function renderContents($writer)
+	{
+		parent::renderChildren($writer);
+	}
+
+	/**
+	 * Renders the closing tag for the control
+	 * This method is invoked when {@link getTagName TagName} is not empty.
+	 * @param THtmlWriter the writer used for the rendering purpose
+	 */
+	public function renderEndTag($writer)
+	{
+		$writer->renderEndTag();
+	}
+}
+
+?>
\ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TRepeater.php b/framework/Web/UI/WebControls/TRepeater.php
index 2483f361..3d5b194b 100644
--- a/framework/Web/UI/WebControls/TRepeater.php
+++ b/framework/Web/UI/WebControls/TRepeater.php
@@ -979,115 +979,6 @@ class TRepeaterItem extends TControl implements INamingContainer, IItemDataRende
 }
 
 
-/**
- * TRepeaterItemRenderer class
- *
- * TRepeaterItemRenderer can be used as a convenient base class to
- * define an item renderer class for {@link TRepeater}.
- *
- * Because TRepeaterItemRenderer extends from {@link TTemplateControl}, derived child classes
- * can have templates to define their presentational layout.
- *
- * TRepeaterItemRenderer implements {@link IItemDataRenderer} interface,
- * which enables the following properties that are related with data-bound controls:
- * - {@link getItemIndex ItemIndex}: zero-based index of this control in the repeater item collection.
- * - {@link getItemType ItemType}: item type of this control, such as TListItemType::AlternatingItem
- * - {@link getData Data}: data associated with this control
-
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.1.0
- */
-class TRepeaterItemRenderer extends TTemplateControl implements IItemDataRenderer
-{
-	/**
-	 * index of the data item in the Items collection of repeater
-	 */
-	private $_itemIndex;
-	/**
-	 * type of the TRepeaterItem
-	 * @var TListItemType
-	 */
-	private $_itemType;
-	/**
-	 * data associated with this item
-	 * @var mixed
-	 */
-	private $_data;
-
-	/**
-	 * @return TListItemType item type
-	 */
-	public function getItemType()
-	{
-		return $this->_itemType;
-	}
-
-	/**
-	 * @param TListItemType item type.
-	 */
-	public function setItemType($value)
-	{
-		$this->_itemType=TPropertyValue::ensureEnum($value,'TListItemType');
-	}
-
-	/**
-	 * Returns a value indicating the zero-based index of the item in the corresponding data control's item collection.
-	 * If the item is not in the collection (e.g. it is a header item), it returns -1.
-	 * @return integer zero-based index of the item.
-	 */
-	public function getItemIndex()
-	{
-		return $this->_itemIndex;
-	}
-
-	/**
-	 * Sets the zero-based index for the item.
-	 * If the item is not in the item collection (e.g. it is a header item), -1 should be used.
-	 * @param integer zero-based index of the item.
-	 */
-	public function setItemIndex($value)
-	{
-		$this->_itemIndex=TPropertyValue::ensureInteger($value);
-	}
-
-	/**
-	 * @return mixed data associated with the item
-	 */
-	public function getData()
-	{
-		return $this->_data;
-	}
-
-	/**
-	 * @param mixed data to be associated with the item
-	 */
-	public function setData($value)
-	{
-		$this->_data=$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 TRepeaterCommandEventParameter($this,$sender,$param));
-			return true;
-		}
-		else
-			return false;
-	}
-}
-
-
 /**
  * TRepeaterItemCollection class.
  *
diff --git a/framework/Web/UI/WebControls/TRepeaterItemRenderer.php b/framework/Web/UI/WebControls/TRepeaterItemRenderer.php
new file mode 100644
index 00000000..fa0b2aca
--- /dev/null
+++ b/framework/Web/UI/WebControls/TRepeaterItemRenderer.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * TRepeaterItemRenderer class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2007 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Id$
+ * @package System.Web.UI.WebControls
+ */
+
+Prado::using('System.Web.UI.WebControls.TRepeater');
+
+/**
+ * TRepeaterItemRenderer class
+ *
+ * TRepeaterItemRenderer can be used as a convenient base class to
+ * define an item renderer class for {@link TRepeater}.
+ *
+ * Because TRepeaterItemRenderer extends from {@link TTemplateControl}, derived child classes
+ * can have templates to define their presentational layout.
+ *
+ * TRepeaterItemRenderer implements {@link IItemDataRenderer} interface,
+ * which enables the following properties that are related with data-bound controls:
+ * - {@link getItemIndex ItemIndex}: zero-based index of this control in the repeater item collection.
+ * - {@link getItemType ItemType}: item type of this control, such as TListItemType::AlternatingItem
+ * - {@link getData Data}: data associated with this control
+
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id$
+ * @package System.Web.UI.WebControls
+ * @since 3.1.0
+ */
+class TRepeaterItemRenderer extends TTemplateControl implements IItemDataRenderer
+{
+	/**
+	 * index of the data item in the Items collection of repeater
+	 */
+	private $_itemIndex;
+	/**
+	 * type of the TRepeaterItem
+	 * @var TListItemType
+	 */
+	private $_itemType;
+	/**
+	 * data associated with this item
+	 * @var mixed
+	 */
+	private $_data;
+
+	/**
+	 * @return TListItemType item type
+	 */
+	public function getItemType()
+	{
+		return $this->_itemType;
+	}
+
+	/**
+	 * @param TListItemType item type.
+	 */
+	public function setItemType($value)
+	{
+		$this->_itemType=TPropertyValue::ensureEnum($value,'TListItemType');
+	}
+
+	/**
+	 * Returns a value indicating the zero-based index of the item in the corresponding data control's item collection.
+	 * If the item is not in the collection (e.g. it is a header item), it returns -1.
+	 * @return integer zero-based index of the item.
+	 */
+	public function getItemIndex()
+	{
+		return $this->_itemIndex;
+	}
+
+	/**
+	 * Sets the zero-based index for the item.
+	 * If the item is not in the item collection (e.g. it is a header item), -1 should be used.
+	 * @param integer zero-based index of the item.
+	 */
+	public function setItemIndex($value)
+	{
+		$this->_itemIndex=TPropertyValue::ensureInteger($value);
+	}
+
+	/**
+	 * @return mixed data associated with the item
+	 */
+	public function getData()
+	{
+		return $this->_data;
+	}
+
+	/**
+	 * @param mixed data to be associated with the item
+	 */
+	public function setData($value)
+	{
+		$this->_data=$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 TRepeaterCommandEventParameter($this,$sender,$param));
+			return true;
+		}
+		else
+			return false;
+	}
+}
+
+?>
\ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TWebControl.php b/framework/Web/UI/WebControls/TWebControl.php
index 33393843..9120ae0e 100644
--- a/framework/Web/UI/WebControls/TWebControl.php
+++ b/framework/Web/UI/WebControls/TWebControl.php
@@ -38,7 +38,7 @@ Prado::using('System.Web.UI.WebControls.TWebControlAdapter');
  * @package System.Web.UI.WebControls
  * @since 3.0
  */
-class TWebControl extends TControl
+class TWebControl extends TControl implements IStyleable
 {
 	/**
 	 * Copies basic control attributes from another control.
@@ -283,6 +283,14 @@ class TWebControl extends TControl
 			throw new TInvalidDataValueException('webcontrol_style_invalid',get_class($this));
 	}
 
+	/**
+	 * Removes all style data.
+	 */
+	public function clearStyle()
+	{
+		$this->clearViewState('Style');
+	}
+
 	/**
 	 * @return integer the tab index of the control
 	 */
-- 
cgit v1.2.3