Можно ли сделать элемент в элементе управления «Список Flex» недоступным для выбора? - PullRequest
0 голосов
/ 13 января 2010

Можно ли сделать элемент в элементе управления списком недоступным для выбора? Если это так, как это будет сделано?

Я попробовал одну вещь до сих пор. Я использовал пользовательское средство визуализации элементов, которое проверяет значение в свойстве данных после события FlexEvent.DATA_CHANGE. Если это значение не установлено, я попытался установить для свойства selectable свойства средства визуализации элементов значение false. Это, к сожалению, не похоже на работу.

Есть идеи?

Ответы [ 5 ]

1 голос
/ 29 декабря 2010

Мне удалось решить проблему невозможности выбора первого / последнего элементов, просто выполнив эти функции verticalScrollPosition ++ и verticalScrollPosition - непосредственно перед caretIndex ++ и caretIndex-- соответственно (в примере, который Майкл связал с приведенным выше) Я не мог поверить, что исправить это было так легко, но это было!

1 голос
/ 16 января 2010

Итак, я нашел собственное решение. Он похож на ваш, и, кажется, делает свое дело и охватывает все основы, кроме взлома клавиш вверх и вниз страницы. Я говорю хак, потому что я не уверен, что он обрабатывает увеличение или уменьшение значения caretIndex так же, как элемент управления List. По сути, он просто вручную устанавливает значение 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;
}
0 голосов
/ 01 мая 2013

Я сам искал решение, и вот решение, которое я придумал. Обратите внимание, что я использую список искры. Я надеюсь, что кто-то найдет это полезным.

  1. Реализация обоих обработчиков событий для изменения и изменения
  2. Установите выделение на -1 и requireSelection на false, чтобы ничего не было выбрано
  3. При создании провайдера данных включайте / отключайте элементы по своему усмотрению
  4. Предоставьте некоторую логику в изменяющемся обработчике для вызова 'protectDefault' для события, если оно не включено или не должно быть выбрано.

Пример: взято из моей реализации, где я создаю свои собственные элементы и использую макет плитки

<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>
0 голосов
/ 03 июня 2010

Просто подумал, что добавлю два своих чувства. Мне было интересно то же самое (как настроить список без возможности выбора), и я понял, что группа данных компонента spark сделает именно это. Конечно, вам нужно использовать Flex 4, но если вы хотите, и мне интересно, могу ли я установить в своем списке невозможность выбора, я бы предложил использовать группу данных.

0 голосов
/ 13 января 2010

Я смог сделать это, чтобы добавить компонент-разделитель, следуя этому примеру ComboBox . Вот пример с удаленной логикой рендеринга и оставленной логикой выбора:

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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...