代码之家  ›  专栏  ›  技术社区  ›  Matt W

是否可以使灵活列表控件中的项不可选?

  •  0
  • Matt W  · 技术社区  · 15 年前

    是否可以使列表控件中的项不可选?如果是这样,这将如何实现?

    到目前为止,我试过一件事。我所做的是使用一个自定义项渲染器,在flexevent.data_change事件时检查数据属性中的值。如果没有设置该值,我尝试将项目呈现器的Selectable属性设置为false。不幸的是,这似乎不起作用。

    有什么想法吗?

    5 回复  |  直到 12 年前
        1
  •  1
  •   Matt W    15 年前

    所以我想出了自己的解决办法。它类似于你的,并且似乎做的诀窍,并涵盖所有的基础,除了黑客网页向上和向下键。我说hack,因为我不确定它是否像list控件那样处理caretindex的增加或减少。基本上,它只是在下一个可选项是什么之前手动将CaretIndex设置为索引,并将键代码更改为简单的向上或向下。

    protected function disabledFilterFunction( data:Object ):Boolean
    {
        return ( data != null && data.data == null );
    }
    
    override protected function mouseEventToItemRenderer( event:MouseEvent ):IListItemRenderer
    {
        var item:IListItemRenderer = super.mouseEventToItemRenderer( event );
    
        if( item && item.data && disabledFilterFunction( item.data ) )
            return null;
    
        return item;
    }
    
    override protected function moveSelectionVertically( code:uint, shiftKey:Boolean, ctrlKey:Boolean ):void
    {
        var i:int;
        var newIndex:int;
    
        switch( code )
        {
            case Keyboard.UP:
                newIndex = getPreviousUnselectableIndex( caretIndex - 1 );
                break;
    
            case Keyboard.DOWN:
                newIndex = getNextUnselectableIndex( caretIndex + 1 );
                break;
    
            case Keyboard.HOME:
                newIndex = getFirstSelectableIndex();
                code = Keyboard.UP;
                break;
    
            case Keyboard.END:
                newIndex = getLastSelectableIndex();
                code = Keyboard.DOWN;
                break;
    
            case Keyboard.PAGE_UP:
            {
                newIndex = Math.max( getFirstSelectableIndex(), getPreviousUnselectableIndex( caretIndex - ( rowCount - 2 ) ) );
                code = Keyboard.UP;
                break;
            }
    
            case Keyboard.PAGE_DOWN:
            {
                newIndex = Math.min( getLastSelectableIndex(), getNextUnselectableIndex( caretIndex + ( rowCount - 1 ) ) );
                code = Keyboard.DOWN;
                break;
            }
        }
    
        if( newIndex > -1 && newIndex < collection.length )
        {
            caretIndex = newIndex;
            super.moveSelectionVertically( code, shiftKey, ctrlKey );
        }
    }
    
    private function getFirstSelectableIndex():int
    {
        var result:int = -1;
    
        for( var i:int = 0; i < collection.length; i++ )
        {
            if( !disabledFilterFunction( collection[i] ) )
            {
                result = i + 1;
                break;
            }
        }
    
        return result;
    }
    
    private function getLastSelectableIndex():int
    {
        var result:int = -1;
    
        for( var i:int = collection.length - 1; i > -1; i-- )
        {
            if( !disabledFilterFunction( collection[i] ) )
            {
                result = i - 1;
                break;
            }
        }
    
        return result;
    }
    
    private function getPreviousUnselectableIndex( startIndex:int ):int
    {
        var result:int = -1;
    
        for( var i:int = startIndex; i > -1; i-- )
        {
            if( !disabledFilterFunction( collection[i] ) )
            {
                result = i + 1;
                break;
            }
        }
    
        return result;
    }
    
    private function getNextUnselectableIndex( startIndex:int ):int
    {
        var result:int = collection.length;
    
        for( var i:int = startIndex; i < collection.length; i++ )
        {
            if( !disabledFilterFunction( collection[i] ) )
            {
                result = i - 1;
                break;
            }
        }
    
        return result;
    }
    
        2
  •  1
  •   David    14 年前

    我可以通过分别在caretindex++和caretindex之前执行这个verticalscrollposition++和verticalscrollposition来解决第一个/最后一个项目不可选择的问题(在上面Michael链接到的示例中)。我真不敢相信这么容易就修好了,但确实如此!

        3
  •  0
  •   Michael Brewer-Davis    15 年前

    我可以这样做来添加一个分隔符组件,如下所示 ComboBox example . 下面是一个示例,其中去除了渲染器逻辑,保留了可选择性逻辑:

    package com.example.ui  {
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;
    
    import mx.controls.List;
    import mx.controls.listClasses.IListItemRenderer;
    
    public class MyList extends List
    {
        public function MyList()
        {
            super();
        }
    
    
        /** Override mouse navigation */
        protected override function mouseEventToItemRenderer(event:MouseEvent):IListItemRenderer {
            var row:IListItemRenderer = super.mouseEventToItemRenderer(event);
    
            if (row != null && isSelectable(row.data)) {
                return null;
            }
            return row;
        }
    
        /** Override keyboard navigation */
        protected override function moveSelectionVertically(code:uint, shiftKey:Boolean, ctrlKey:Boolean):void {
            super.moveSelectionVertically(code, shiftKey, ctrlKey);
    
            if (code == Keyboard.DOWN && isSeparatorData(selectedItem)) {
                caretIndex++;
            }
            if (code == Keyboard.UP && isSeparatorData(selectedItem)) {
                caretIndex--;
            }
            finishKeySelection();           
        }
    
        /**
         * Define this mechanism in a way that makes sense for your project.
         */
        protected function isSelectable(data:Object):Boolean {
            return data != null && data.hasOwnProperty("type") && data.type == "separator";
        }
    
    }
    }
    

    更好地处理可滚动列表和连续分隔符的替代(仍然不完善):

        protected override function moveSelectionVertically(code:uint, shiftKey:Boolean, ctrlKey:Boolean):void {
            super.moveSelectionVertically(code, shiftKey, ctrlKey);
    
            var newCode:uint = singleLineCode(code);
            var item:Object = selectedItem;
            var itemChanged:Boolean = true;
    
            while (!isNaN(newCode) && itemChanged && isSeparatorData(item)) {
                super.moveSelectionVertically(newCode, shiftKey, ctrlKey);
                itemChanged = (item === selectedItem);
                item = selectedItem;
            }
        }
    
        private function singleLineCode(code:uint):uint {
            switch (code) {
            case Keyboard.UP:
            case Keyboard.PAGE_UP:
                return Keyboard.UP;
                break;
            case Keyboard.DOWN:
            case Keyboard.PAGE_DOWN:
                return Keyboard.DOWN;
                break;
            default:
                return NaN;
                break;                              
            }
            return code;
        }
    
        4
  •  0
  •   mrjrdnthms    15 年前

    只是想加上我的两种感觉。我在想同样的事情(如何将列表设置为不可选),我意识到Spark组件数据组会做到这一点。当然,您需要使用flex 4,但是如果您需要,并且想知道我是否可以将列表设置为不可选,我建议您使用数据组。

        5
  •  0
  •   Leo O'Donnell    12 年前

    我自己在寻找解决方案,这是我想出的解决方案。注意,我正在使用一个火花列表。我希望有人能帮上忙。

    1. 实现用于更改和更改的事件处理程序
    2. 将选择设置为-1,并将RequireSelection设置为False,以便不选择任何内容。
    3. 构建数据提供程序时,根据需要启用/禁用项
    4. 在更改处理程序中提供一些逻辑,以便在未启用或不应选择事件时调用“PreventDefault”。

    例子: 从我的实现中筛选出我自己的项并使用平铺布局

    <s:List id="myListView"
        itemRenderer="spark.skins.spark.DefaultComplexItemRenderer"
        horizontalCenter="0"
        verticalCenter="0"
        borderVisible="false"
        dataProvider="{myItems}"
        change="changeHandler(event)" changing="changingHandler(event)"
        requireSelection="false"
        selectedIndex="-1" >
        <s:layout>
            <s:TileLayout verticalGap="0" />
        </s:layout>
    </s:List>
    <fx:script>
        <![CDATA[
            import mx.collections.ArrayCollection;            
            import spark.events.IndexChangeEvent;
    
            [Bindable]
            public var myItems = new ArrayCollection;
    
    
            protected function startup():void {
                // Here's where you'd build up your items if they
                // need to be built dynamically.
            }
    
            protected function changeHandler(event:IndexChangeEvent):void
            {
                var currentIndx:int = event.currentTarget.selectedIndex;
                var selectedItem:UIComponent = event.currentTarget.selectedItem as UIComponent;
    
                // Do whatever you need to do on selection here
            }
    
            protected function canMicrophoneChange(event:IndexChangeEvent):void
            {
                var currentIndx:int = event.currentTarget.selectedIndex;
                var selectedItem:UIComponent = event.currentTarget.selectedItem as UIComponent;
    
                // This will cancel the select if the item was not enabled.
                if (selectedItem.enabled == false) event.preventDefault();
            }
        ]]>
    </fx:script>
    
    推荐文章