Flex 带时间的DateField的

要做一个带时间的DateField控件。不做啰嗦,直接上代码

App:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" 
			   minWidth="955" minHeight="600" xmlns:control="com.view.control.*">
	<fx:Script>
		<![CDATA[
			[Bindable]private var timeMode:Boolean;
			protected function button1_clickHandler(event:MouseEvent):void
			{
				timeMode = !timeMode;
			}
		]]>
	</fx:Script>
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<s:Button label="Change Mode" click="button1_clickHandler(event)"/>
	<control:DateTimeField timeStampMode="{timeMode}" yearNavigationEnabled="true"/>
</s:Application>

 DateTimeField:

package com.view.control
{
	import flash.events.Event;
	import flash.events.FocusEvent;
	
	import mx.controls.DateChooser;
	import mx.controls.DateField;
	import mx.controls.dataGridClasses.DataGridListData;
	import mx.controls.listClasses.BaseListData;
	import mx.controls.listClasses.ListData;
	import mx.core.ClassFactory;
	import mx.core.IFactory;
	import mx.events.CalendarLayoutChangeEvent;
	import mx.events.DropdownEvent;
	import mx.events.FlexEvent;
	import mx.formatters.DateFormatter;
	import mx.logging.Log;
	import mx.managers.PopUpManager;
	import mx.managers.PopUpManagerChildList;
	import mx.utils.ObjectUtil;
	
	public class DateTimeField extends DateField
	{
		// using custom data to avoid beeing overwritten
		protected var _cData:Object;
		protected var _cListData:BaseListData;
		protected var _cSelectedDate:Date = null;
		
		// copied vars
		protected var updateDateFiller:Boolean;
		protected var selectedDateSet:Boolean;
		protected var selectedDateChanged:Boolean = false;
		protected var show:Boolean = false;
		private var _timeStampMode:Boolean = true;
		private var _timeStampModeChanged:Boolean;
		private var _dateTimeChooserDropdownFactory:IFactory = new ClassFactory(DateTimeChooser);
		private var _dateChooserDropdownFactory:IFactory = new ClassFactory(DateChooser);
		private var _dropdownFactory:IFactory = new ClassFactory(DateChooser);
		public function DateTimeField()
		{
			super();
			parseFunction = customerParseFunction;
			this.labelFunction = labelDateTime;
			this.addEventListener(DropdownEvent.OPEN,handleDropdown);
			this.addEventListener(DropdownEvent.CLOSE,handleDropdown);
		}
		
		// -------------------------------
		// own functions
		// -------------------------------
		public function set timeStampMode(value:Boolean):void
		{
			_timeStampMode = value;
			_timeStampModeChanged = true;
			if(value)
			{
				dropdownFactory = _dateTimeChooserDropdownFactory;
			}
			else
			{
				dropdownFactory = _dateChooserDropdownFactory;
			}
			invalidateProperties();
			invalidateSize();
		}
		
		public function get timeStampMode():Boolean
		{
			return _timeStampMode;
		}
		protected function handleDropdown(e:DropdownEvent):void
		{
			if (e.type == DropdownEvent.CLOSE)
			{
				// save new date without beeing cropped
				if (ObjectUtil.dateCompare(selectedDate,dropdown.selectedDate) != 0)
				{
					setUpdateDate();
				}
				show = false;
			}
			else
			{
				show = true;
				dateFiller(_cSelectedDate);
			}	
		}
		
		private function setUpdateDate():void
		{
			selectedDate = dropdown.selectedDate;
			updateData();
		}
		
		protected function updateData():void
		{
			// if new date selected,save it to the data-binding variable
			if (data && selectedDate)
			{
				if (listData && listData is DataGridListData)
					data[DataGridListData(listData).datafield] = selectedDate;
				else if (listData is ListData && ListData(listData).labelField in value)
					data[ListData(listData).labelField] = selectedDate;
				else if (value is String)
					data = selectedDate.toString();
				else
					data = value as Date;
			}
		}
		
		// -------------------------------
		// change Label
		// -------------------------------
		protected function numberToTime(value:Number):String
		{
			return (value >= 10) ? String(value) : ("0" + value);
		}
		
		protected function labelDateTime(value:Date):String
		{
			if (value)	
			{
				if(timeStampMode)
				{
					return DateField.datetoString(value,formatString) + " " + numberToTime(value.hours) + ":" + numberToTime(value.minutes);
				}
				else
				{
					return DateField.datetoString(value,formatString);
				}
				
			}
			else
			{
				return "";
			}
		}
		
		// -------------------------------
		// overwritten data functions
		// -------------------------------
		
		override public function get data():Object
		{
			return _cData;
		}
		
		override public function set data(value:Object):void
		{
			var newDate:Date;
			
			_cData = value;
			
			if (_cListData && _cListData is DataGridListData)
				newDate = _cData[DataGridListData(_cListData).datafield];
			else if (_cListData is ListData && ListData(_cListData).labelField in _cData)
				newDate = _cData[ListData(_cListData).labelField];
			else if (_cData is String)
				newDate = new Date(Date.parse(data as String));
			else
				newDate = _cData as Date;
			
			if (!selectedDateSet)
			{
				selectedDate = newDate;
				selectedDateSet = false;
			}
			
			dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
		}
		
		override public function get listData():BaseListData
		{
			return _cListData;
		}
		
		
		override public function set listData(value:BaseListData):void
		{
			_cListData = value;
		}
		
		//----------------------------------
		//  selectedDate
		//----------------------------------
		
		[Bindable("change")]
		[Bindable("valueCommit")]
		[Bindable("selectedDateChanged")]
		[Inspectable(category="General")]
		
		override public function get selectedDate():Date
		{
			return _cSelectedDate;
		}
		
		/**
		 *  @private
		 */
		override public function set selectedDate(value:Date):void
		{
			if (ObjectUtil.dateCompare(_cSelectedDate,value) == 0) 
				return;
			
			selectedDateSet = true;
			_cSelectedDate = value;
			updateDateFiller = true;
			selectedDateChanged = true;
			
			invalidateProperties();
			
			// Trigger bindings to 'selectedData'.
			dispatchEvent(new Event("selectedDateChanged"));
			
			dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
		}
		
		
		//--------------------------------------------------------------------------
		//
		//  Overridden methods: UIComponent
		//
		//--------------------------------------------------------------------------
		override protected function commitProperties():void
		{
			super.commitProperties();
			
			if (updateDateFiller)
			{
				updateDateFiller = false;
				dateFiller(_cSelectedDate);
			}
			
			if (selectedDateChanged)
			{
				selectedDateChanged = false;
				dropdown.selectedDate = _cSelectedDate;
			}
			if(_timeStampModeChanged)
			{
				_timeStampModeChanged = false;
				this.dispatchEvent(new Event(Event.REMOVED_FROM_STAGE));
				var editable:Boolean = textInput.editable;
				super.createChildren();
				this.yearNavigationEnabled = this.yearNavigationEnabled;
				textInput.editable = editable;
			}
		}
		
		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------
		private function dateFiller(value:Date):void
		{
			if (labelFunction != null)
				textInput.text = labelFunction(value);
			else
				textInput.text = datetoString(value,formatString);
		}
		
		//--------------------------------------------------------------------------
		//
		//  Event handlers
		//
		//--------------------------------------------------------------------------
		override protected function downArrowButton_buttonDownHandler(event:FlexEvent):void
		{
			if (show)
			{
				close();
			}
			else 
			{
				if(text == "")
				{
					selectedDate = new Date();
					dropdown.selectedDate = selectedDate;
				}
				open();
			}
			dateFiller(_cSelectedDate);
		}
		
		//----------------------------------
		//  dropdownFactory // Overwrite,to include the own DateTimeChooser class
		//----------------------------------
		
		[Bindable("dropdownFactoryChanged")]
		override public function get dropdownFactory():IFactory
		{
			return _dropdownFactory;
		}
		
		override public function set dropdownFactory(value:IFactory):void
		{
			_dropdownFactory = value;
			dispatchEvent(new Event("dropdownFactoryChanged"));
		}
		
		// -------------------------------
		// Remove focus handler
		// -------------------------------
		override protected function focusOutHandler(event:FocusEvent):void
		{
			setActualDate();
		}
		
		override protected function textInput_changeHandler(event:Event):void
		{
			super.textInput_changeHandler(event);
			setActualDate();
		}
		
		private function setActualDate():void
		{
			if(text == "")
			{
				selectedDate = null;
			}
			else
			{
				var inputDate:Date = customerParseFunction(text);
				text = labelDateTime(inputDate);
				selectedDate = inputDate;
			}
		}
		
		override public function open():void
		{
			selectedDate = DateFormatter.parseDateString(text);
			super.open();
		}
		
		private function customerParseFunction(text:String,format:String = null):Date
		{
			var date:Date = DateFormatter.parseDateString(text);
			if(date && (date.fullYear >9999 || date.fullYear < 1000))
			{
				date = null;
			}
			return date;
		}
		
		
	}
}

 DateTimeChooser:

 

 

package com.view.control
{
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	
	import mx.controls.DateChooser;
	import mx.controls.Label;
	import mx.controls.TextInput;
	import mx.events.CalendarLayoutChangeEvent;
	
	public class DateTimeChooser extends DateChooser
	{
		private var textInput:TextInput;
		private var label:Label;
		
		[Bindable] private var startTime:String = "";
		private var _timeLabel:String = "";
		
		public function DateTimeChooser()
		{
			super();
			timeLabel = "Time";
		}
		
		override public function get selectedDate():Date
		{
			// add time
			var d:Date = (super.selectedDate) ? super.selectedDate : new Date();
			
			var times:Array = (textInput) ? textInput.text.split(":") : startTime.split(":");
			if (times.length > 1)
			{
				d.hours = times[0];
				d.minutes = times[1];
			}
			
			// update data
			super.selectedDate = d;

			return d;
		}
		
		override public function set selectedDate(value:Date):void
		{
			if (value)
			{
				startTime = to2Digits(value.hours) + ":" + to2Digits(value.minutes);
				if (textInput) textInput.text = startTime;
				
				super.selectedDate = value;
			}
		}
		
		[Bindable]
		public function get timeLabel():String { return _timeLabel; }
		public function set timeLabel(value:String):void { _timeLabel = value; }
		
		private function to2Digits(value:Number = NaN):String
		{
			if (isNaN(value))	return "00";
			else if (value < 10)return "0" + value;
			else				return "" + value;
		}
		
		private function checkTimeBox(e:KeyboardEvent):void
		{
			if (e.keyCode == Keyboard.ENTER) // bei ENTER schließen
			{
				dispatchEvent(new CalendarLayoutChangeEvent(CalendarLayoutChangeEvent.CHANGE,false,selectedDate));
			}
			else // ansonsten überprüfe ob der String stimmt
			{
				var values:Array = String(textInput.text).match(/[0-9]{2}/g);
				textInput.text = to2Digits(values[0]) + ":" + to2Digits(values[1]);
			}
		}
		private function timeFocusOut(e:FocusEvent):void
		{
			dispatchEvent(new CalendarLayoutChangeEvent(CalendarLayoutChangeEvent.CHANGE,selectedDate));
		}
		
		/**
		 *  @private
		 *  Erstellt noch den Time NumericStepper
		 */
		override protected function createChildren():void
		{
			super.createChildren();
			
			if (!textInput){
				textInput = new Textinput();
				textInput.text = startTime;
				textInput.maxChars = 5;
				textInput.addEventListener(KeyboardEvent.KEY_DOWN,checkTimeBox);
				textInput.owner = this;
				textInput.addEventListener(FocusEvent.FOCUS_OUT,timeFocusOut);
				addChild(textInput);
			}
			if (!label) {
				label = new Label();
				label.setStyle("textAlign","right");
				label.text = timeLabel;
				addChild(label);
			}
		}
		
		/**
		 *  @private
		 */
		override protected function updatedisplayList(unscaledWidth:Number,unscaledHeight:Number):void
		{
			super.updatedisplayList(unscaledWidth,unscaledHeight);
			
			var borderThickness:Number = getStyle("borderThickness");
			var cornerRadius:Number = getStyle("cornerRadius");
			var borderColor:Number = getStyle("borderColor");
			
			var w:Number = unscaledWidth - borderThickness*2;
			var h:Number = unscaledHeight - borderThickness*2;
			
			textInput.setActualSize(48,20);
			textInput.move(w - 50,h - 22);
			
			label.setActualSize(36,20);
			label.move(textInput.x - 40,h - 21);
		}
	}
}

相关文章

一:display:flex布局display:flex是一种布局方式。它即可以...
1. flex设置元素垂直居中对齐在之前的一篇文章中记载过如何...
移动端开发知识点pc端软件和移动端apppc端软件是什么,有哪些...
最近挺忙的,准备考试,还有其他的事,没时间研究东西,快周...
display:flex;把容器设置为弹性盒模型(设置为弹性盒模型之后...
我在网页上运行了一个Flex应用程序,我想使用Command←组合键...