Professional Documents
Culture Documents
Tutorial 4 - Creating A Custom Property Sheet
Tutorial 4 - Creating A Custom Property Sheet
2009-11-03
Tutorial 4 - Creating a custom property sheet
Introduction
Introduction
This tutorial assumes that you have at least some knowledge of Cascading
Style Sheet (CSS), ActionScript 3.0, and MXML, the XML-based markup
language introduced by Adobe Flex.
The concentration of the tutorial is creating a custom property sheet for those
who do not want to use the default property sheet. We will include Flex
controls in the property sheet so that all of the properties and styles of the
custom component can be exposed. We will also use a sample CSS definition
to style the property sheet to look more like the Xcelsius color scheme.
Download the source code for the custom component so that you could see
what properties and styles it has. You will need to reference the names of
the properties/styles inside the property sheet source code.
For demonstration purposes, only the basic controls for the layout of custom
property sheet are mentioned. Please see the CustomPropSheetHorizon
talSlider sample source code for a more advanced layout.
3. After laying out the controls, switch to Source mode, you should have the
following code:
SizeEditor.value)" />
<mx:Label x="23" y="136" text="Color"
width="119"/>
<mx:HRule y="141" height="10" right="28"
left="62"/>
<mx:Label x="43" y="169" text="Title Col
or:" width="116"/>
<mx:ColorPicker id="titleColorEditor"
x="137" y="169" change="proxy.setStyle('titleFontCol
or', uint(titleColorEditor.selectedColor))" />
</mx:Canvas>
</mx:ViewStack>
<mx:TabBar x="0" y="0" dataProvider="viewstack1">
</mx:TabBar>
</mx:Application>
<mx:Style />
<mx:Script>
<![CDATA[
]]>
</mx:Script>
2. Right click on the project folder in the Navigation window and create a
new folder named style; then import PSStyle.css, located in the SDK
install folder: SDK\samples\CustomPropSheetHorizontalSlid
er\CustomPropSheetHorizontalSliderPropertySheet\style\.
This CSS definition file contains several tags that define the styles for
each of them. These styles definitions were chosen because they closely
match Xcelsius property sheet styles: background color is #F4F3EE,
fontFamily is Tahoma, text color is black, etc.
3. Modify the source of <mx:Style> tag to include PSStyle.css: <mx:Style
source="style\PSStyle.css"/>
import mx.containers.*;
import mx.controls.*;
import mx.core.Container;
import mx.events.FlexEvent;
import xcelsius.binding.BindingDirection;
import xcelsius.binding.tableMaps.input.In
putBindings;
import xcelsius.binding.tableMaps.output.Out
putBindings;
import xcelsius.propertySheets.impl.Proper
tySheetExternalProxy;
import xcelsius.propertySheets.inter
faces.PropertySheetFunctionNamesSDK;
[Bindable]
private var _fontNames:Array = [];
[Bindable]
protected var _fontSizes:Array = new Ar
ray("8", "9", "10", "11", "12", "14", "16", "18", "20",
"22");
• _fontNames will contain system fonts that the user can choose from.
• _fontSizes is the list of selectable font sizes.
Both of these variables need to be bindable since we bind them to the data
providers of the combo boxes on the "Appearance" tab.
Variable propertyToBind stores the name of the property that the user is
binding, and currentBindingID stores the current binding id (null if there's
no binding) for the property.
The function init() sets the callback to continueBind method when the
user is picking Excel cell(s) to bind to, and then notifies Xcelsius that it has
finished loading the property sheet. Refer to the API Documentation for the
list of function name constants. The retrieval of the list of system fonts is
In initValues(), we first get the array of values for the Xcelsius custom
component properties using proxy.getProperties method, then the
array of values for the styles using proxy. getStyles method. Both
methods need a list of property or style names passed in as an array of
strings.
Next, we process through the arrays retrieving the name and value of each
property and style, and either displaying that value to the corresponding
control's default value or the cell address(es) if bound to the Excel
spreadsheet. If a property has binding capability, make use of getProper
tyBindDisplayName method and add an if-else statement to handle that
correctly.
{
titleFontSizeEditor.text
= styleValue.toString();
}
else
{
titleFontSizeEditor.se
lectedIndex = -1;
}
break;
default:
break;
}
}
}
Given a property name, initiateBind allows the user to select the Excel
spreadsheet cell(s) to bind to an Xcelsius custom component property. If
there is an existing binding for that property, show that in the Excel binding
selection window and store the currentBindingID (null if there is no
current binding) in case we "continueBinding". Use the function proxy.re
questUserSelection method to let the user choose where to bind to in
the Excel spreadsheet.
ings[0];
}
propertyToBind = propertyName;
proxy.requestUserSelection(current
BindingID);
}
continueBind method completes the binding when the user has finished
selecting the cell(s) to bind to or cleared the binding. Again, we process
through each property that has binding capability to do the following: filling
the control with current value and set property when the user explicitly clears
binding, disabling the option to manually enter a value once the component
if the property is bound, displaying the range address, and the actual binding
using proxy.bind method. BindingDirection.BOTH updates the custom
component property when the spreadsheet changes and also updates the
spreadsheet when the custom component changes. InputBindings.SIN
GLETON writes to a single cell in the spreadsheet. OutputBindings.SIN
GLETON reads a single cell in the spreadsheet.
For more information on bindings and the custom property sheet API, refer
to Appendix B in the Xcelsius 2008 Component SDK SP1 User Guide.
var propertyValues:Array;
var propertyObject:Object;
var bindingAddresses:Array;
if (currentBindingID != null)
{
proxy.unbind(currentBindingID);
currentBindingID = null;
}
switch (propertyName)
{
case "value":
if ((bindingID == null) ||
(bindingID == ""))
{
valueEditor.enabled = true;
propertyValues = proxy.get
Properties([propertyName]);
propertyObject = propertyVal
ues[0];
valueEditor.text = property
Object.value;
proxy.setProperty(property
Name, propertyObject.value);
return;
}
valueEditor.enabled = false;
valueEditor.text = proxy.getBind
ingDisplayName(bindingID);
proxy.bind("value", null,
bindingID, BindingDirection.BOTH, InputBindings.SINGLE
TON, OutputBindings.SINGLETON);
break;
default:
break;
}
}
Save and build.