MXML AS3 Set Button Default Height, Allow Override - actionscript-3

I have a component that extends spark.components.Button
I used this new component for all buttons that I am using on my application. Now I want to set a default height for the buttons, these are the specs
By default buttons have a default height set on AS3.
On mxml, if height value is set it will override the default height.
Tried setting the $this->height value but it won't allow overrides to the default.
How can I do this?

This code worked for me.
public class CustomButton extends Button
{
private static var defaultHeight:Number = 50;
public function CustomButton()
{
super();
}
override protected function createChildren(): void
{
trace("height:"+this.explicitHeight); // If didn't set height at MXML, explicitHeight returns NaN.
if (!this.explicitHeight)
{
this.height = defaultHeight;
}
super.createChildren();
}
}
<local:CustomButton x="0" y="0" label="Button1" height="30" />
<local:CustomButton x="0" y="100" label="Button2" />

Related

Flex DataGrid Header Column Separator

I'm using an mx:DataGrid (in a Halo theme) and I'm having some issues with the header column separators/vertical grid line colors. Does anyone know how to customize/change the line color?
Thanks!
--Moe
Datagrid has two styles horizontalSeparatorSkin and verticalSeparatorSkin style which you can override. It seems you need to override the later.
<mx:DataGrid id="grid" verticalGridLines="true" verticalSeparatorSkin="{VerticalSeparatorSkin}">
<mx:columns>
<mx:DataGridColumn dataField="lbl" />
<mx:DataGridColumn dataField="val"/>
</mx:columns>
</mx:DataGrid>
Now you can write this class as:
public class VerticalSeparatorSkin extends ProgrammaticSkin
{
public function VerticalSeparatorSkin()
{
super();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
// draw a line at the bottom of the rectangle defined by
// unscaledWidth and unscaledHeight
var g:Graphics = this.graphics;
g.clear();
g.lineStyle(3, 0x00FF00); // change thickness / color here
g.moveTo(0,unscaledWidth);
g.lineTo(unscaledWidth, unscaledHeight);
}
}
This should do the work. Another option is to customize the datagrid itself.
public class MyCustomGrid extends DataGrid
{
public function MyCustomGrid()
{
super();
}
override protected function drawVerticalLine(s:Sprite, colIndex:int, color:uint, x:Number):void
{
var contentHolder:ListBaseContentHolder = s.parent.parent as ListBaseContentHolder;
var g:Graphics = s.graphics;
g.lineStyle(3, color); // change the thickness here
g.moveTo(x, 0);
g.lineTo(x, contentHolder.height);
}
}
And this can be used then in place of regular DataGrid.

Close Flyout which contains a UserControl

I am building a user control for a TextBox because I want it to have some special behaviour.
The control can be used in several contexts, including as a flyout for a button. When it is a flyout I want to close the flyout when the user presses the Enter key while editing text.
To achieve this, the control has a ParentButton dependency property which, if set, stores the button with the flyout, and the XAML for the parent page sets it in this case. The control has a KeyUp handler which detects the Enter key and, if ParentButton property is set, closes its flyout.
TextBoxUC.xaml
<UserControl
x:Class="TextBoxUCDemo.TextBoxUC"
...
xmlns:local="using:TextBoxUCDemo"
...>
<StackPanel Width="250">
<TextBox KeyUp="TextBox_KeyUp" Text="Hello" />
</StackPanel>
TextBoxUC.xaml.cs
public sealed partial class TextBoxUC : UserControl
{
public TextBoxUC() {
this.InitializeComponent();
}
internal static readonly DependencyProperty ParentButtonProperty =
DependencyProperty.Register("ParentButton", typeof(Button), typeof(TextBoxUC), new PropertyMetadata(null));
public Button ParentButton {
get { return ((Button)GetValue(ParentButtonProperty)); }
set { SetValue(ParentButtonProperty, value); }
}
private void TextBox_KeyUp(object sender, KeyRoutedEventArgs e) {
switch (e.Key) {
case VirtualKey.Enter:
// (Do something with the Text...)
// If this is a flyout from a button then hide the flyout.
if (ParentButton != null) { // Always null!
ParentButton.Flyout.Hide();
}
break;
default: return;
}
}
}
MainPage.xaml
<Page
x:Class="TextBoxUCDemo.MainPage"
...
xmlns:local="using:TextBoxUCDemo"
...>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="200,300">
<Button Name="flyoutTextBoxButton" Content="Edit">
<Button.Flyout>
<Flyout>
<local:TextBoxUC ParentButton="{Binding ElementName=flyoutTextBoxButton, Path=.}"/>
</Flyout>
</Button.Flyout>
</Button>
</Grid>
The problem is that the ParentButton is always null.
-- Edit --
I've narrowed the problem down to the binding to the element in the XAML. If I set the ParentButton from the code-behind of the MainPage, then it works.
In 'MainPage.xaml':
Loaded="Page_Loaded"
....
<local:TextBoxUC/>
In MainPage.xaml.cs
private void Page_Loaded(object sender, RoutedEventArgs e) {
textBoxUC.ParentButton = this.flyoutTextBoxButton;
}
Effect:
if (ParentButton != null) {
// Reaches here
}
So: THE PROBLEM is in the xaml ParentButton="{Binding ElementName=flyoutTextBoxButton, Path=.}", which compiles but has no effect.
If I add a changed event handler to the registration of the dependency property, then the handler is called when the ParentButton is set from the code-behind, but never called for the binding to the ElementName. The handler seems to be only useful for debugging purposes. I can't see that it is needed to make the property work.
Okay, how about this? I've used it in the past. Works fine.
[Microsoft.Xaml.Interactivity.TypeConstraint(typeof(Windows.UI.Xaml.Controls.TextBox))]
public class CloseFlyoutOnEnterBehavior : DependencyObject, IBehavior
{
public DependencyObject AssociatedObject { get; set; }
public void Attach(DependencyObject obj)
{
this.AssociatedObject = obj;
(obj as TextBox).KeyUp += TextBox_KeyUp;
}
void TextBox_KeyUp(object sender, KeyRoutedEventArgs e)
{
if (!e.Key.Equals(Windows.System.VirtualKey.Enter))
return;
var parent = this.AssociatedObject;
while (parent != null)
{
if (parent is FlyoutPresenter)
{
((parent as FlyoutPresenter).Parent as Popup).IsOpen = false;
return;
}
else
{
parent = VisualTreeHelper.GetParent(parent);
}
}
}
public void Detach()
{
(this.AssociatedObject as TextBox).KeyUp -= TextBox_KeyUp;
}
}
Use it like this:
<Button HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="Click Me">
<Button.Flyout>
<Flyout Placement="Bottom">
<TextBox Width="200"
Header="Name"
PlaceholderText="Jerry Nixon">
<Interactivity:Interaction.Behaviors>
<local:CloseFlyoutOnEnterBehavior />
</Interactivity:Interaction.Behaviors>
</TextBox>
</Flyout>
</Button.Flyout>
</Button>
Learn more about behaviors here:
http://blog.jerrynixon.com/2013/10/everything-i-know-about-behaviors-in.html
And here (lesson 3):
http://blog.jerrynixon.com/2014/01/the-most-comprehensive-blend-for-visual.html
Best of luck!
You can add to your control normal property of type Action that will contain lambda expression.
You will set this property when creating control and then invoke it inside your control on EnterPressed event.
public class MyControll
{
public Action ActionAfterEnterPressed {get; set;}
private void HandleOnEnterPressed()
{
if(ActionAfterEnterPressed != null)
{
ActionAfterEnterPressed.Invoke();
}
}
}
somwhere where you create your control
...
MyControl c = new MyControl()
c.ActionAfterEnterPressed = CloseFlyuot;
....
private void CloseFlyuot()
{
_myFlyout.IsOpen = false;
}
This way you can set any action and invoke it when needed from inside of your control withou needing to bother with what action actually does.
Best of luck.
You're making it a dependency property. That's the first, right start. But until you handle the changed event, you aren't really going to get any value from it.
I discuss this more here:
http://blog.jerrynixon.com/2013/07/solved-two-way-binding-inside-user.html
Best of luck!

Tabbing does not work in mx:TileList component

I am using mx:Tilelist component to display set of textfields on screen, but when i try to traverse the fields through TAB foucs move out of the list. Please provide solution for this problem. Following is the code i am using
<mx:TileList id="tileList"
dataProvider="{collection}"
change="setCurrentIndex(tileList.selectedIndex);"
dataChange="setCurrentIndex(tileList.selectedIndex);"
columnCount="1"
columnWidth="345"
itemRenderer="components.InputParamIR"
rowHeight="30"
verticalScrollPolicy="auto"
horizontalScrollPolicy="auto"
backgroundColor="#EEEEEE"
dragEnabled="false"
dragMoveEnabled="true"
dropEnabled="true"
width="100%" height="100%"
itemClick="chartTileClick(event);"
/>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.containers.Panel;
[Bindable]
public var index:uint;
[Bindable]
public var collection:ArrayCollection = new ArrayCollection();
[Bindable]
public var isVisible:Boolean ;
public function initEventsLocal(event:Event):void
{
this.initEvents(event);
collection = new ArrayCollection();
isVisible = false;
}
private function chartTileClick(event:ListEvent):void
{
event.currentTarget.tabFocusEnabled=true;
event.currentTarget.tabEnabled=true;
}
]]>
</fx:Script>
In Flex List Itemrenderer may not get the focus since it is non editable and it will not implement the focus manager interface, you need to implement IFocusManagerComponent in your item renderer components.InputParamIR also you have to override your TileList class to enable tab for childrens.
package
{
import mx.controls.TileList;
public class MyTileList extends TileList
{
override protected function createChildren():void {
super.createChildren();
this.listContent.tabChildren = this.tabChildren
this.listContent.tabEnabled = this.tabEnabled
}
}
}
Have a look in to these
Tile list item renderer text focus solved
Issues with keyboard navigation on list with custom renderer
i hope this will help you
happy coding...

Adding images inside a Tooltip in Flex 4

I am trying to insert images and other html content inside a Tooltip in Flex 4 by making the text htmlText similar to this:
http://blogagic.com/190/easy-flex-tooltip-customization-using-html-tags
My HTMLToolTip class:
package custom
{
import mx.controls.ToolTip;
public class HTMLToolTip extends ToolTip
{
public function HTMLToolTip()
{
super();
}
override protected function commitProperties():void{
super.commitProperties();
textField.htmlText = text;
}
}
}
and on Tooltip Creation, I set the class as the ToolTipManager class
protected function helpToolTip_toolTipCreateHandler(event:ToolTipEvent):void
{
ToolTipManager.toolTipClass = HTMLToolTip;
helpToolTip.tooltip = "<img src='ui_graphic/testimage.png' width='20' height='20'/> this is a <b>tool</b> tip";
}
But it just doesn't seem to work anymore in Flex 4 (judging from various comments online too). The images just don't show up. Every other basic HTML-tag I have tried work fine. Has anyone gotten this to work on Flex 4, or should I look into another (more complex) solution?
Create tooltip class extends RichText:
package classes
{
import mx.core.IToolTip;
import spark.components.RichText;
import spark.utils.TextFlowUtil;
public class RichToolTip extends RichText implements IToolTip
{
public function RichToolTip()
{
super();
mouseEnabled = false;
mouseChildren = false;
setStyle("backgroundColor", "0xeeeeee");
}
override public function set text(value:String):void
{
textFlow = TextFlowUtil.importFromString(value);
}
}
}
In application set new tooltip class:
ToolTipManager.toolTipClass = RichToolTip;
And add tooltip for example over button:
btn.toolTip = "<div><img source='assets/bender_saved.png' width='20' height='20' /><p>this is a test <span fontWeight='bold'>bold</span></p></div>";

Swing tooltip resizable

I've tried to implement a resizeable tooltip but have some problems with this.
When the tooltip is shown, the text updates on change in the model (implemented with property change listener). What I need now is, that the tooltip changes its size as well depending on the text.
Tried revalidate, doLayout and repaint but with no effect. The tooltip doesn't change its size.
Only moving the mouse gives me a correct sizing for the first text which is displayed in the tooltip.
Can anybody help?
Here are some code snippets: first of all my tolltip class:
public class ResizeableToolTip extends JToolTip {
public ResizeableToolTip(final JComponent component) {
super(component);
initComponents();
}
#Override
protected void initGUI() {
super.initGUI();
setLayout(new BorderLayout());
}
/**
* Component initialization goes here...
*/
private void initComponents() {
setTipText(getComponent().getToolTipText());
setPreferredSize(calculateOptimalSize());
}
private abstract Dimension calculateOptimalSize();
#Override
public void setTipText(String tipText) {
super.setTipText(tipText);
setPreferredSize(calculateOptimalSize());
revalidate();
}
}
Then I have a button which is using this implementation:
public class MyButton extends JButton implements PropertyChangeListener {
//...
private ResizeableToolTip tooltip;
//...
private initComponents() {
//...
tooltip = new ResizeableToolTip(this);
//...
}
//...
public void propertyChange(final PropertyChangeEvent pcevt) {
//...
if (MyButtonModel.TOOLTIPTEXT_PROPERTY.equals(pcevt.getPropertyName()) {
tooltip.setTiptext((String) pcevt.getNewValue());
tooltip.repaint();
}
//...
}
//...
}
The result should be a tooltip which is displayed over the button where the text is changing when s.th. changes in the data model. The text changes are working but the size of the box of the tooltip stays on the wrong size.
As far as i can tell there is not way to resize it besides moving the mouse. However the component should have one mouse mouse motion listener so all you have to do is call mouseMoved on that and it will think the mouse has been moved and will resize the tooltip.
//comp will be whatever component your tooltip is on
if(comp.getMouseMotionListeners().length > 0)comp.getMouseMotionListeners()[0].mouseMoved(new MouseEvent(inst, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), 0, MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo().getLocation().y, 0, false));
Just call that after you set the tooltip and it should resize.