Actionscript 3 - 在列表条目被禁用时从 Combobox Dataprovider(XML 列表)中删除条目
Actionscript3 - Removing entry from Comobox Data Provider (XMLlist) when list entry is disabled
我修改的代码不是我写的,而且我对 Actionscript 的经验很少。
目前,菜单项在禁用时显示为灰色。这是通过以下 类:
实现的
DisabledComboBox
(扩展 ComboBox)
DisabledList
(扩展列表)
DisabledListItemRenderer
(扩展标签)
菜单约束存储在一个大 XML 变量 MenuChoiceXML
中。每个 DisabledComboBox
引用一个 XMLlist
,它是 MenuChoiceXML
的一个子集作为它的 DataProvider
。 XMLlists
中的每个列表条目都有一个 elementsID(整数)。
MenuChoiceXML
中还有一个 XMLlist
完整菜单约束,这些约束是根据数据库中可用的内容预先组装的。他们使用以下形式:
- 选择 15 约束 5、12、23
也就是说,在一个DisabledComboBox
中选择了15,在另一个DisabledComboBoxes
中选择了5,12和23,并且它们不能被选择。
与其将它们变灰并禁用选择它们的 MouseEvent,不如将它们从 DataProvider
XMLlist
.
中完全删除
这些是我认为相关的代码:
约束项XMLlist
<Constraints>
<Cstr choice="DataProvider1" selectedValue="2" constrains="DataProvider2" denies="4,7,12" />
</Constraints>
TotalStateofProgram.as
public function applyConstraints():void
{
// before updating menus all constrained menus enable all menu choices, then turn on restricted options
for each(var menulist:String in constrainedMenuList)
{
for each(var xmlentry:XML in MenuChoicesXML.descendants(menulist).MenuItem)
{
xmlentry.@enabled=true;
}
}
// Save constraints in XMLlist
var cstrs:XMLList = MenuChoicesXML.descendants("Constraints").Cstr;
// go through each contraint in list of constraints
for each(var cstr:XML in cstrs)
{
var choice:String = cstr.@choice;
var value:String = cstr.@selectedValue;
// for each constraint - find if it is required constraint selectedValue matches current selection
var applies:Boolean = (design.getData(choice) == value);
if(applies)
{
var menuname:String = cstr.@constrains;
var denies:String = cstr.@denies;
var deniesarray:Array = denies.split(',');
// Go throught items which are denied by selection
for(var i:int = 0; i<deniesarray.length;i++)
{
var d:String = deniesarray[i];
// If something that is to be constrained is currently selected, unselect it from DisabledComboBox
if(design.getData(menuname) == d)
design.setData(menuname, "0"); // default elementsId for unselected is 0
// set disable menu choice for this elementsId
(MenuChoicesXML.descendants(menuname).MenuItem.(@elementsId == d)).@enabled = "false";
}
}
}
}
前面的代码重置了所有约束,然后使用当前选择的菜单项将约束应用于其他菜单项。重要的一点是这一行:
(MenuChoicesXML.descendants(menuname).MenuItem.(@elementsId == d)).@enabled = "false";
它似乎正在查找 XMLlist
中的项目并将其禁用。禁用后,DisabledList
和 DisabledListItemRenderer
会看到这一点,其中所选项目变为灰色并且附加到它的 MouseEvent 被禁用。 (我将 post 稍后实现的代码,因为我不是 100% 相关)
我意识到通常使用 ComboBox.removeItem()
,但我不确定如何使用 elementsID
查找 ComboBox
或 DataProvider
(如上所示) ).
以下是我的一些问题:
我可以查找 DataProvider
中包含 XMLlist
条目的 ComboBox
并使用 ComboBox.removeItem()
吗?怎么样?
我可以利用 XMLlist
条目被禁用的事实将其从列表中删除吗?
还有其他我没有考虑的方式吗?
我将致力于总结使 DataProvide
r 的列表条目变灰的代码。我不确定它是否相关,因为变灰是对构成 DisabledComboBox
的 DataProvider
的列表中的文本执行的,但是我想从 DisabledCombobox
中删除该元素(这看起来工作量少了)。
可能相关代码:
DisabledComboBox.as
package com.cwmlib.controls
{
import mx.controls.ComboBox;
import mx.core.ClassFactory;
import mx.events.FlexEvent;
public class DisabledComboBox extends ComboBox
{
public function DisabledComboBox()
{
super();
this.dropdownFactory = new ClassFactory(DisabledList);
this.itemRenderer = new ClassFactory(DisabledListItemRenderer);
}
}
}
DisabledList.as
package com.cwmlib.controls
{
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import mx.controls.ComboBox;
import mx.core.ClassFactory;
import mx.controls.List;
import mx.controls.listClasses.IListItemRenderer;
import mx.controls.listClasses.ListItemRenderer;
public class DisabledList extends List
{
public function DisabledList()
{
super();
this.itemRenderer = new ClassFactory(DisabledListItemRenderer);
}
private function itemDisable(event:MouseEvent):Boolean
{
var item:IListItemRenderer = mouseEventToItemRenderer(event);
if (item != null && item.data != null
&& ((item.data is XML && item.data.@enabled == 'false')
|| item.data.enabled==false || item.data.enabled=='false')
)
{
return true;
}
else
{
return false;
}
}
}
}
DisabledListItemRenderer.as
package com.cwmlib.controls
{
import mx.controls.Label;
public class DisabledListItemRenderer extends Label
{
private var _enabled:Boolean = true;
public function DisabledListItemRenderer()
{
super();
}
override public function set data(value:Object):void
{
if (value != null && ((value is XML && value.@enabled == 'false')
|| value.enabled == false || value.enabled == 'false')
){
this._enabled = false;
}
else
{
this._enabled = true;
}
super.data = value;
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (!this._enabled) {
textField.setColor(getStyle("disabledColor"));
}
else
{
textField.setColor(getStyle("color"));
}
}
}
}
如果您 select 在另一个组合框中删除某些项目,那么您想删除一个组合框中的某些项目吗?如果您 select 其他东西,可能会再次显示它们?在这种情况下,filterFunction 听起来是合适的工具。未经测试,但这会给你一个想法:
// make a dedicated _myDataProvider for the filtered combobox and assign a filterfunction to it
_myDataProvider.filterFunction = filterCollection;
// Assign the dataProvider
filteredCombobox.dataProvider = _myDataProvider;
// filter the dataprovider when selection in the first combobox will change
selectionComboBox.addEventListener(Event.CHANGE, onComboBoxChange);
private function onComboBoxChange(e:Event):void
{
// refresh the dataprovider, that will apply the filter
_myDataProvider.refresh();
}
private function filterCollection(item:Object):Boolean
{
// here you need to know the condition for the filter depending on the selection in the first combobox (prbably the selected item in the selection combobox?)
// this filterCollection function will run trough each item in the _myDataProvider and return true (keep the item in the list) or false (the item will disappear)
if (condition)
return true;
else
return false;
}
请记住,应用过滤器后,_myDataProvider 将仅包含当前可见的项目。如果您再次需要完整的集合,您可以使用
重置数据提供者
_myDataprovider.filterFunction = null;
_myDataprvider.refresh();
编辑:
整个 XML 操作对我来说听起来很痛苦。摆脱自定义组合框和 XML。解析您的 XML 并制作两个数据提供者 - 一个用于 selection 组合框,它将具有值对象,此拒绝 属性:
public class SelectionVO
{
public var label:String;
public var denies:Array; // for example, ["2", "3", "4"];
}
还有一个用于过滤组合框的值对象,该对象将具有用于检查是否应过滤掉该项目的 ID:
public class FilteredItemVO
{
public var label:String;
public var myID:String; // for example, "3"
}
然后当 selection 组合框发生变化时,您可以过滤集合:
private function filterCollection(item:Object):Boolean
{
var selectedVO:SelectionVO = selectionComboBox.selectedItem as SelectionVO;
// show this item if its myID is NOT included in the selected vo's denies array
if (selectedVO:SelectionVO.denies.indexOf(item.myID) == -1)
return true;
else
return false;
}
我修改的代码不是我写的,而且我对 Actionscript 的经验很少。
目前,菜单项在禁用时显示为灰色。这是通过以下 类:
实现的DisabledComboBox
(扩展 ComboBox)DisabledList
(扩展列表)DisabledListItemRenderer
(扩展标签)
菜单约束存储在一个大 XML 变量 MenuChoiceXML
中。每个 DisabledComboBox
引用一个 XMLlist
,它是 MenuChoiceXML
的一个子集作为它的 DataProvider
。 XMLlists
中的每个列表条目都有一个 elementsID(整数)。
MenuChoiceXML
中还有一个 XMLlist
完整菜单约束,这些约束是根据数据库中可用的内容预先组装的。他们使用以下形式:
- 选择 15 约束 5、12、23
也就是说,在一个DisabledComboBox
中选择了15,在另一个DisabledComboBoxes
中选择了5,12和23,并且它们不能被选择。
与其将它们变灰并禁用选择它们的 MouseEvent,不如将它们从 DataProvider
XMLlist
.
这些是我认为相关的代码:
约束项XMLlist
<Constraints>
<Cstr choice="DataProvider1" selectedValue="2" constrains="DataProvider2" denies="4,7,12" />
</Constraints>
TotalStateofProgram.as
public function applyConstraints():void { // before updating menus all constrained menus enable all menu choices, then turn on restricted options for each(var menulist:String in constrainedMenuList) { for each(var xmlentry:XML in MenuChoicesXML.descendants(menulist).MenuItem) { xmlentry.@enabled=true; } } // Save constraints in XMLlist var cstrs:XMLList = MenuChoicesXML.descendants("Constraints").Cstr; // go through each contraint in list of constraints for each(var cstr:XML in cstrs) { var choice:String = cstr.@choice; var value:String = cstr.@selectedValue; // for each constraint - find if it is required constraint selectedValue matches current selection var applies:Boolean = (design.getData(choice) == value); if(applies) { var menuname:String = cstr.@constrains; var denies:String = cstr.@denies; var deniesarray:Array = denies.split(','); // Go throught items which are denied by selection for(var i:int = 0; i<deniesarray.length;i++) { var d:String = deniesarray[i]; // If something that is to be constrained is currently selected, unselect it from DisabledComboBox if(design.getData(menuname) == d) design.setData(menuname, "0"); // default elementsId for unselected is 0 // set disable menu choice for this elementsId (MenuChoicesXML.descendants(menuname).MenuItem.(@elementsId == d)).@enabled = "false"; } } } }
前面的代码重置了所有约束,然后使用当前选择的菜单项将约束应用于其他菜单项。重要的一点是这一行:
(MenuChoicesXML.descendants(menuname).MenuItem.(@elementsId == d)).@enabled = "false";
它似乎正在查找 XMLlist
中的项目并将其禁用。禁用后,DisabledList
和 DisabledListItemRenderer
会看到这一点,其中所选项目变为灰色并且附加到它的 MouseEvent 被禁用。 (我将 post 稍后实现的代码,因为我不是 100% 相关)
我意识到通常使用 ComboBox.removeItem()
,但我不确定如何使用 elementsID
查找 ComboBox
或 DataProvider
(如上所示) ).
以下是我的一些问题:
我可以查找
DataProvider
中包含XMLlist
条目的ComboBox
并使用ComboBox.removeItem()
吗?怎么样?我可以利用
XMLlist
条目被禁用的事实将其从列表中删除吗?还有其他我没有考虑的方式吗?
我将致力于总结使 DataProvide
r 的列表条目变灰的代码。我不确定它是否相关,因为变灰是对构成 DisabledComboBox
的 DataProvider
的列表中的文本执行的,但是我想从 DisabledCombobox
中删除该元素(这看起来工作量少了)。
可能相关代码:
DisabledComboBox.as
package com.cwmlib.controls
{
import mx.controls.ComboBox;
import mx.core.ClassFactory;
import mx.events.FlexEvent;
public class DisabledComboBox extends ComboBox
{
public function DisabledComboBox()
{
super();
this.dropdownFactory = new ClassFactory(DisabledList);
this.itemRenderer = new ClassFactory(DisabledListItemRenderer);
}
}
}
DisabledList.as
package com.cwmlib.controls
{
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import mx.controls.ComboBox;
import mx.core.ClassFactory;
import mx.controls.List;
import mx.controls.listClasses.IListItemRenderer;
import mx.controls.listClasses.ListItemRenderer;
public class DisabledList extends List
{
public function DisabledList()
{
super();
this.itemRenderer = new ClassFactory(DisabledListItemRenderer);
}
private function itemDisable(event:MouseEvent):Boolean
{
var item:IListItemRenderer = mouseEventToItemRenderer(event);
if (item != null && item.data != null
&& ((item.data is XML && item.data.@enabled == 'false')
|| item.data.enabled==false || item.data.enabled=='false')
)
{
return true;
}
else
{
return false;
}
}
}
}
DisabledListItemRenderer.as
package com.cwmlib.controls
{
import mx.controls.Label;
public class DisabledListItemRenderer extends Label
{
private var _enabled:Boolean = true;
public function DisabledListItemRenderer()
{
super();
}
override public function set data(value:Object):void
{
if (value != null && ((value is XML && value.@enabled == 'false')
|| value.enabled == false || value.enabled == 'false')
){
this._enabled = false;
}
else
{
this._enabled = true;
}
super.data = value;
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (!this._enabled) {
textField.setColor(getStyle("disabledColor"));
}
else
{
textField.setColor(getStyle("color"));
}
}
}
}
如果您 select 在另一个组合框中删除某些项目,那么您想删除一个组合框中的某些项目吗?如果您 select 其他东西,可能会再次显示它们?在这种情况下,filterFunction 听起来是合适的工具。未经测试,但这会给你一个想法:
// make a dedicated _myDataProvider for the filtered combobox and assign a filterfunction to it
_myDataProvider.filterFunction = filterCollection;
// Assign the dataProvider
filteredCombobox.dataProvider = _myDataProvider;
// filter the dataprovider when selection in the first combobox will change
selectionComboBox.addEventListener(Event.CHANGE, onComboBoxChange);
private function onComboBoxChange(e:Event):void
{
// refresh the dataprovider, that will apply the filter
_myDataProvider.refresh();
}
private function filterCollection(item:Object):Boolean
{
// here you need to know the condition for the filter depending on the selection in the first combobox (prbably the selected item in the selection combobox?)
// this filterCollection function will run trough each item in the _myDataProvider and return true (keep the item in the list) or false (the item will disappear)
if (condition)
return true;
else
return false;
}
请记住,应用过滤器后,_myDataProvider 将仅包含当前可见的项目。如果您再次需要完整的集合,您可以使用
重置数据提供者_myDataprovider.filterFunction = null;
_myDataprvider.refresh();
编辑:
整个 XML 操作对我来说听起来很痛苦。摆脱自定义组合框和 XML。解析您的 XML 并制作两个数据提供者 - 一个用于 selection 组合框,它将具有值对象,此拒绝 属性:
public class SelectionVO
{
public var label:String;
public var denies:Array; // for example, ["2", "3", "4"];
}
还有一个用于过滤组合框的值对象,该对象将具有用于检查是否应过滤掉该项目的 ID:
public class FilteredItemVO
{
public var label:String;
public var myID:String; // for example, "3"
}
然后当 selection 组合框发生变化时,您可以过滤集合:
private function filterCollection(item:Object):Boolean
{
var selectedVO:SelectionVO = selectionComboBox.selectedItem as SelectionVO;
// show this item if its myID is NOT included in the selected vo's denies array
if (selectedVO:SelectionVO.denies.indexOf(item.myID) == -1)
return true;
else
return false;
}