2008-12-11

show一下我的TreeGrid

折腾了好多天才算做出来。IE7下测试开发的,结果到IE6下一看,全乱了,后来改了CSS就可以了。显示时有点小BUG,不过不影响大局。速度慢,数据量大时就挂掉了,所以实际用的时候加了分页显示。

扩展DateChooser类使之可以突出显示特殊日期

花了将近一天时间,总算整出来了。


----------------------
calendar_test.mxml:
----------------------


xmlns:calendar="calendar.*" layout="absolute" creationComplete="init()">


import mx.controls.Alert;
private function init():void
{
dateChooser.addSpecialDate(new Date(2008, 0, 1));
dateChooser.addSpecialDate(new Date(2008, 4, 1), 0xFFF000);
dateChooser.addSpecialDate(new Date(2008, 9, 1), 0xFFF000);

dateChooser.addSpecialDate(new Date(2008, 11, 1));
dateChooser.addSpecialDate(new Date(2008, 11, 10), 0x00FF00);
dateChooser.addSpecialDate(new Date(2008, 11, 12), 0x0000FF);
dateChooser.addSpecialDate(new Date(2008, 11, 25), 0xFFF000);
}
]]>







----------------------
CustomDateChooser.as:
----------------------

package calendar
{

import mx.controls.DateChooser;
import mx.core.mx_internal;
import mx.events.CalendarLayoutChangeEvent;
import mx.events.DateChooserEvent;
import mx.styles.StyleProxy;

use namespace mx_internal;

public class CustomDateChooser extends DateChooser
{

public static const SPECIALDATE_BACKGROUNDCOLOR:Number = 0xFF0000;

public function CustomDateChooser()
{
super();
}

// 添加特殊日期及显示的背景色(背景色是-1时为透明色)
public function addSpecialDate(date:Date,
backgroundColor:Number = SPECIALDATE_BACKGROUNDCOLOR):void
{
var grid:CustomCalendarLayout = CustomCalendarLayout(mx_internal::dateGrid);
var object:Object = new Object;
object.date = date;
object.backgroundColor = backgroundColor;
grid.specialDateList.push(object);
grid.update();
}

// 移除需要特殊显示的日期
public function removeSpecialDate(date:Date):void
{
var grid:CustomCalendarLayout = CustomCalendarLayout(mx_internal::dateGrid);
var i:int = 0;
for (i = 0; i < grid.specialDateList.length; i++)
{
if (grid.specialDateList[i].date == date)
{
grid.specialDateList.splice(i, 1);
grid.update();
break;
}
}
}

// 返回特殊日期数组
public function getSpecialDateList():Array
{
var grid:CustomCalendarLayout = CustomCalendarLayout(mx_internal::dateGrid);
var array:Array = new Array();
var i:int = 0;
for (i = 0; i < grid.specialDateList.length; i++)
array.push(grid.specialDateList[i].date,
grid.specialDateList[i].backgroundColor);
return array;
}

override protected function createChildren():void
{
super.createChildren();
if (mx_internal::dateGrid)
removeChild(mx_internal::dateGrid);
mx_internal::dateGrid = new CustomCalendarLayout();
mx_internal::dateGrid.styleName = new StyleProxy(this, calendarLayoutStyleFilters);
addChild(mx_internal::dateGrid);
mx_internal::dateGrid.addEventListener(CalendarLayoutChangeEvent.CHANGE,
dateGrid_changeHandler);
mx_internal::dateGrid.addEventListener(DateChooserEvent.SCROLL,
dateGrid_scrollHandler);
}

private function dateGrid_scrollHandler(event:DateChooserEvent):void
{
dispatchEvent(event);
}

private function dateGrid_changeHandler(event:CalendarLayoutChangeEvent):void
{
selectedDate = CustomCalendarLayout(event.target).selectedDate;
var e:CalendarLayoutChangeEvent = new
CalendarLayoutChangeEvent(CalendarLayoutChangeEvent.CHANGE);
e.newDate = event.newDate;
e.triggerEvent = event.triggerEvent;
dispatchEvent(e);
}

}

}


------------------------
CustomCalendarLayout.as:
------------------------

package calendar
{

import flash.events.MouseEvent;

import mx.controls.CalendarLayout;
import mx.core.IUITextField;
import mx.core.mx_internal;

use namespace mx_internal;

public class CustomCalendarLayout extends CalendarLayout
{

public var specialDateList:Array = new Array();

private var currentLabelName:String = "";
private var lastLabelColumnIndex:int = -1;
private var lastLabelRowIndex:int = -1;
private var lastLabelBackground:Boolean = false;

public function CustomCalendarLayout()
{
super();
addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}

public function update():void
{
updateDisplayList(width, height);
}

override protected function updateDisplayList(
unscaledWidth:Number, unscaledHeight:Number):void
{
var array:Array = new Array();
var date:Date = null;
var i:int = 0;
var j:int = 0;
var k:int = 0;
var day:Number = 0;
super.updateDisplayList(unscaledWidth, unscaledHeight);
for (i = 0; i < specialDateList.length; i++)
{
date = specialDateList[i].date;
if (date.getFullYear() == CustomDateChooser(this.parent).displayedYear &&
date.getMonth() == CustomDateChooser(this.parent).displayedMonth)
array.push(specialDateList[i]);
}
for (i = 0; i < mx_internal::dayBlocksArray.length; i++)
{
for (j = 0; j < mx_internal::dayBlocksArray[i].length; j++)
{
mx_internal::dayBlocksArray[i][j].background = false;
day = Number(mx_internal::dayBlocksArray[i][j].text);
if (isNaN(day) == false)
{
for (k = 0; k < array.length; k++)
{
if (day == array[k].date.getDate() &&
mx_internal::dayBlocksArray[i][j].name != currentLabelName)
{
if (array[k].backgroundColor >= 0)
{
mx_internal::dayBlocksArray[i][j].background = true;
mx_internal::dayBlocksArray[i][j].backgroundColor =
array[k].backgroundColor;
}
}
}
}
}
}
}

private function mouseMoveHandler(event:MouseEvent):void
{
var currentX:int = -1;
var currentY:int = -1;
var currentBackground:Boolean = false;
var i:int = 0;
var j:int = 0;
var label:IUITextField = null;
for (i = 0; i < mx_internal::dayBlocksArray.length; i++)
{
for (j = 0; j < mx_internal::dayBlocksArray[i].length; j++)
{
label = mx_internal::dayBlocksArray[i][j];
if (label.mouseX == event.localX && label.mouseY == event.localY)
{
if (i != lastLabelColumnIndex || j != lastLabelRowIndex)
{
currentX = i;
currentY = j;
currentBackground = label.background;
label.background = false;
}
}
else
{
if (i == lastLabelColumnIndex && j == lastLabelRowIndex &&
label.name != currentLabelName)
label.background = lastLabelBackground;
}
}
}
if (currentX != -1 || currentY != -1)
{
lastLabelColumnIndex = currentX;
lastLabelRowIndex = currentY;
lastLabelBackground = currentBackground;
}
}

private function mouseUpHandler(event:MouseEvent):void
{
var i:int = 0;
var j:int = 0;
var label:IUITextField = null;
currentLabelName = "";
for (i = 0; i < mx_internal::dayBlocksArray.length; i++)
{
for (j = 0; j < mx_internal::dayBlocksArray[i].length; j++)
{
label = mx_internal::dayBlocksArray[i][j];
if (label.mouseX == event.localX && label.mouseY == event.localY)
{
currentLabelName = label.name;
break;
}
}
}
}

}

}