2

I am using spark DropDownLists and I don't want to see any horizontal scrollbars in the dropdown. I'm OK with the dropdown being wider than the anchor, so I have a custom skin that sets popUpWidthMatchesAnchorWidth to false. But I don't want the dropdown to ever be smaller than the anchor. This is my dilemma.

I came up with a solution that sometimes works, but there is something wrong with it. My DropDownList skin is as follows:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled=".5" minHeight="25"> 

    <fx:Metadata>
    <![CDATA[ 
        [HostComponent("spark.components.DropDownList")]
    ]]>
    </fx:Metadata>

    <fx:Script>
        <![CDATA[
            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
            {
                // anchor width is the min width of the dropdown
                if (dropDown && openButton && popUp && dropDown.getExplicitOrMeasuredWidth() < openButton.getExplicitOrMeasuredWidth())
                    popUp.popUpWidthMatchesAnchorWidth = true;

                super.updateDisplayList(unscaledWidth, unscaledHeight);
            }
        ]]>
    </fx:Script>

    <s:states>
        <s:State name="normal" stateGroups="closed" />
        <s:State name="open" />
        <s:State name="disabled" stateGroups="closed" />
    </s:states>

    <s:PopUpAnchor id="popUp" displayPopUp.normal="false" displayPopUp.open="true" includeIn="open"
        left="0" right="0" top="0" bottom="0" itemDestructionPolicy="auto"
        popUpPosition="below" popUpWidthMatchesAnchorWidth="false">

        <s:Group id="dropDown" maxHeight="134" minHeight="22" >

            <s:RectangularDropShadow id="dropShadow" blurX="20" blurY="20" alpha="0.45" distance="7" 
                 angle="90" color="#000000" left="0" top="0" right="0" bottom="0"/>

            <s:Rect id="border" left="0" right="0" top="0" bottom="0">
                <s:stroke>
                    <s:SolidColorStroke id="borderStroke" weight="1"/>
                </s:stroke>
            </s:Rect>

            <s:Rect id="background" left="1" right="1" top="1" bottom="1" >
                <s:fill>
                    <s:SolidColor color="#222222"/>
                </s:fill>
            </s:Rect>

            <s:Scroller id="scroller" left="0" top="0" right="0" bottom="0" hasFocusableChildren="false" minViewportInset="1">
                <s:DataGroup id="dataGroup" itemRenderer="spark.skins.spark.DefaultItemRenderer">
                    <s:layout>
                        <s:VerticalLayout gap="0" horizontalAlign="contentJustify"/>
                    </s:layout>
                </s:DataGroup> 
            </s:Scroller>
        </s:Group>
    </s:PopUpAnchor>

    <s:Button id="openButton" left="0" right="0" top="0" bottom="0" focusEnabled="false" alpha.disabled="0.5"
        skinClass.closed="assets.skins.dropDownList.dropDownListNormalButtonSkin"
        skinClass.open="assets.skins.dropDownList.dropDownListOpenButtonSkin"/>  

    <s:Label id="labelDisplay" verticalAlign="middle" maxDisplayedLines="1" 
        mouseEnabled="false" mouseChildren="false"
        left="7" right="30" top="2" bottom="2" width="75" verticalCenter="1" /> 

</s:SparkSkin>

This works as expected when the contents of the dropdown are either wider than the anchor or smaller than about 100px, but if I explicitly set the width in the instance of the DropDownList to be something like 200px and the contents of the dropdown are around 150px wide, the dropdown is smaller than the anchor.

Basically, it looks like openButton.getExplicitOrMeasuredWidth() returns about 100, regardless of what I set the DropDownList's width to be.

How can I change this so that I can have multiple DropDownLists with different widths, but always making sure that the dropdown's width is either greater than or equal to the anchor's width?

zero323
  • 322,348
  • 103
  • 959
  • 935
Travesty3
  • 14,351
  • 6
  • 61
  • 98
  • Did you tried to use just `openButton.width` instead of `openButton.getExplicitOrMeasuredWidth()`? – Constantiner Jul 29 '11 at 19:44
  • I suspect the dropDown has some minimum width set somewhere. If I had to guess; I'd say it was in the DataGroup; but that's just a guess. If you really want to do this, you should write your own algorithm for determining drop down width; which is going to be tedious and I expect not efficient since you'll have to renderer every item to be 100% complete. – JeffryHouser Jul 29 '11 at 19:47
  • @Constantiner - sigh...yeah, that worked. Seems dumb to me that they wouldn't be the same, but I guess that's what I get for over-complicating it. I think I needed to use `getExplicitOrMeasuredWidth` to get the dropdown's width, so I just used it on the other side as well, thinking it should get the same value. Post that as an answer and I'll accept it. – Travesty3 Jul 29 '11 at 19:51

2 Answers2

3

You Said: "but if I explicitly set the width in the instance of the DropDownList to be something like 200px and the contents of the dropdown are around 150px wide, the dropdown is smaller than the anchor."

So if you explicitly set the width, then this.width is always reliable. Simply replace the button.getExplicitOrMeasuredWidth() with this.width, problem solved.

if (dropDown && openButton && popUp && dropDown.getExplicitOrMeasuredWidth() < this.width)
                popUp.popUpWidthMatchesAnchorWidth = true;
Jonathan Rowny
  • 7,588
  • 1
  • 18
  • 26
  • This solution also works for me. Giving the answer to @Constantiner because he answered first in a comment on the original post. Thank you for the help, though! – Travesty3 Jul 29 '11 at 19:57
2

I suggest you using openButton.width instead of openButton.getExplicitOrMeasuredWidth().

Constantiner
  • 14,231
  • 4
  • 27
  • 34