【问题标题】:how to create a text stepper control in flex?如何在 flex 中创建文本步进控件?
【发布时间】:2010-06-26 06:11:14
【问题描述】:

我在 Flex 3 中需要一个类似于 NumericStepper 的控件,但它可以显示任意字符串。这种控制存在吗?如果没有,您对创建它有什么建议,或者您会推荐哪些参考资料?

为方便起见,我将其称为 TextStepper。我希望这是一种紧凑的方式来显示用户可以通过单击向上/向下按钮循环浏览的字符串选择列表。紧凑意味着控件没有下拉或弹出方面:更改所选索引的唯一方法是单击向上/向下按钮(更新文本输入值)。值循环意味着我真的想将底层 dataProvider 视为循环缓冲区。所以上/下点击以模方式修改 selectedIndex。

【问题讨论】:

    标签: apache-flex text custom-controls numericstepper


    【解决方案1】:

    想法是使用valueFormatFunction:

    <?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:local="*">
    
        <local:StringStepper horizontalCenter="0" verticalCenter="0" width="200">
            <local:dataProvider>
                <s:ArrayCollection>
                    <fx:String>Hello!</fx:String>
                    <fx:String>I love you.</fx:String>
                    <fx:String>Won't you tell me your name?</fx:String>
                </s:ArrayCollection>
            </local:dataProvider>
        </local:StringStepper>
    
    </s:Application>
    

    StringStepper 的来源:

    package
    {
    import mx.collections.ArrayCollection;
    import mx.events.CollectionEvent;
    
    import spark.components.NumericStepper;
    
    public class StringStepper extends NumericStepper
    {
        public function StringStepper()
        {
            enabled = false;
            valueFormatFunction = defaultValueFormatFunction;
            valueParseFunction = defaultValueParseFunction;
        }
    
        private var _dataProvider:ArrayCollection;
    
        public function get dataProvider():ArrayCollection
        {
            return _dataProvider;
        }
    
        public function set dataProvider(value:ArrayCollection):void
        {
            if (_dataProvider == value)
                return;
    
            if (_dataProvider)
                _dataProvider.removeEventListener(CollectionEvent.COLLECTION_CHANGE,
                    dataProvider_collectionChangeHandler);
    
            _dataProvider = value;
            commitDataProvider();
    
            if (_dataProvider)
                _dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE,
                    dataProvider_collectionChangeHandler);
        }
    
        /**
         * Same event as for <code>value</code>.
         */
        [Bindable("valueCommit")]
        public function get selectedItem():Object
        {
            return _dataProvider && value <= _dataProvider.length - 1 ? _dataProvider[value] : null; 
        }
    
        public function set selectedItem(value:Object):void
        {
            if (!_dataProvider)
                return;
    
            value = _dataProvider.getItemIndex(value);
        }
    
        private function defaultValueFormatFunction(value:Number):String
        {
            return _dataProvider && value <= _dataProvider.length - 1 ? _dataProvider[value] : String(value);
        }
    
        private function defaultValueParseFunction(value:String):Number
        {
            if (!_dataProvider)
                return 0;
    
            var n:int = _dataProvider.length;
            for (var i:int = 0; i < n; i++)
            {
                var string:String = _dataProvider[i];
                if (string == value)
                    return i;
            }
            return 0;
        }
    
        private function commitDataProvider():void
        {
            if (!_dataProvider)
            {
                minimum = 0;
                maximum = 0;
                enabled = false;
                return;
            }
    
            enabled = true;
            minimum = 0;
            maximum = _dataProvider.length - 1;
        }
    
        private function dataProvider_collectionChangeHandler(event:CollectionEvent):void
        {
            commitDataProvider();
        }
    
    }
    }
    

    【讨论】:

    • Maxim,这对 Flex 3 有何改变?
    • 对于 Flex 3,Robusto 的评论中描述了最简单的方法。 Flex 3 中的 NumericStepper 无法以我的方式自定义。
    【解决方案2】:

    我通过将TextInput 覆盖在NumericStepper(绝对定位)上创建了其中一个(作为MXML 组件),以便TextInput 覆盖NumericStepper 的输入部分。

    dataProvider 是一个ArrayCollection 字符串,NumericStepper 的值用于访问 ArrayCollection 中的索引。

    NumericStepper 的更改事件将 TextInput 的文本更改为 dataProvider 的索引 n 处的任何内容。我为组件提供了一个可编辑属性,它将TextInput 设置为可编辑,并将新字符串插入到当前索引处的dataProvider 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-12
      • 1970-01-01
      • 2010-12-01
      相关资源
      最近更新 更多