是否有可能使列表控件中的项目不可选?如果是这样,这将如何完成?是否可以使Flex List控件中的项目不可选?
到目前为止,我已经尝试了一件事。我所做的是使用自定义项目渲染器,在FlexEvent.DATA_CHANGE事件之后检查data属性中的值。如果未设置该值,则尝试将项目渲染器的可选属性设置为false。不幸的是,这似乎并不奏效。
任何想法?
是否有可能使列表控件中的项目不可选?如果是这样,这将如何完成?是否可以使Flex List控件中的项目不可选?
到目前为止,我已经尝试了一件事。我所做的是使用自定义项目渲染器,在FlexEvent.DATA_CHANGE事件之后检查data属性中的值。如果未设置该值,则尝试将项目渲染器的可选属性设置为false。不幸的是,这似乎并不奏效。
任何想法?
所以:
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";
}
}
}
与滚动列表和连续分离交易更好的替代方案(尚不完善)我遇到了我自己的解决方案。它与你的类似,并且似乎能够实现这一诀窍,并且涵盖了除黑客和黑客之外的所有基础。我说黑客,因为我不确定它是否像处理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;
}
我能够做到这一点,添加一个分隔符组件,继此ComboBox example。下面是一个例子与渲染逻辑剥离出来,并在离开可选择性逻辑:
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;
}
这部分工作。它似乎没有考虑到的是列表是可滚动的。假设你的列表的collection/dataProvider中有20个项目,并且列表rowCount(veiwable rows)是10.因此,一个滚动条被渲染。然后让我们说你的集合中的索引9(当列表第一次查看时最后一个可见的行项目)是分隔符。如果您使用箭头键在列表中向下移动,则列表中将选择索引9处的分隔符。 – 2010-01-13 19:26:57
好的结果 - 迄今为止我们还没有在一个可滚动列表中使用它。 它也没有处理连续的分隔符(不太可能用于分隔符的使用,但是用于合理的非可选用法)。仍不能很好地处理不可选择的第一个/最后一个项目。 可以说ListBase中的一个错误isItemSelectable()存在并且可以覆盖,所以键盘导航应该更加注意其结果。 – 2010-01-13 23:35:26
只是想我会加上我的两个意义。我想知道同样的事情(如何设置一个列表不可选),我意识到spark组件数据组完全可以做到这一点。当然你需要使用flex 4,但如果你是,并想知道我可以设置我的列表不可选,我建议使用数据组。
我能够通过简单地在caretIndex ++和caretIndex--之前(在Michael链接上面的示例中)简单地执行verticalScrollPosition ++和verticalScrollPosition来修复第一个/最后一个项不可选择的问题。我无法相信修复是如此简单,但它是!
我一直在寻找解决方案,这里是我想出的解决方案。请注意,我正在使用一个火花列表。我希望有人认为这有帮助。
示例:从我的实现其中那儿剽窃我建立我自己的项目和使用tile布局
<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>
这不好。尝试LIST控件的属性<<< selectable >>>。 – 2010-12-29 09:53:34