SelectedIndex no ComboBox Flex [RESOLVIDO]

Olá pessoal, estou tentando fazer um form para editar um objeto e estou com dificuldade para selecionar o combobox com o valor original do objeto a ser alterado.

Andei pesquisando do google e vi que é usado um for para selecionar o index do combobox. Tentei de várias fomas e não consegui, segue o código:

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()" title="Modifica e-mail" width="600"
	showCloseButton="true" close="PopUpManager.removePopUp(this);">

<mx:Script>
	<![CDATA[
		import mx.controls.Alert;
		import mx.managers.PopUpManager;
		import br.com.crtecnologia.sendmail.entity.mailing.Contact;
		import mx.collections.ArrayCollection;
		import mx.rpc.events.ResultEvent;
		
		[Bindable]
		private var categoryList:ArrayCollection;
		
		public var contact:Contact;
		
		public static const OK:String = "modifyContact_OK";
		
		private function init():void
		{
			PopUpManager.centerPopUp(this);
			listAllCategory();
			nameTxt.text = contact.name;
			emailTxt.text = contact.mail;
			statusModify.selectedValue = contact.status;
			selectComboBox(cbCategory, contact.getCategoryId());
		}
		
		public function selectComboBox(comboBox: ComboBox, id: int): void 
		{
		    var dataProvider:ArrayCollection = ArrayCollection(comboBox.dataProvider);
		    var selectedIndex: int = 0;
		    
		    for (var i:int = 0; i < dataProvider.length; i++) {
		        if (dataProvider[i].id == id) {
		            selectedIndex = i;
		            break;
		        }
		    }
		    comboBox.selectedIndex = i;
		} 
		
		private function listAllCategory():void
		{
			categoryService.listAllCategory();
		}
		
		private function listAllCategoryResult(event:ResultEvent):void
		{
			categoryList = event.result as ArrayCollection;
		}
	]]>
</mx:Script>

<mx:RemoteObject id="categoryService" destination="categoryServices">
	<mx:method name="listAllCategory" result="listAllCategoryResult(event)"/>
</mx:RemoteObject>

<mx:Form width="100%">
	<mx:FormHeading label="Dados do contato" fontSize="10"/>

	<mx:FormItem label="Nome:" width="100%" required="true">
		<mx:TextInput id="nameTxt" width="100%"/>
	</mx:FormItem>

	<mx:FormItem label="E-mail:" width="100%" required="true">
		<mx:TextInput id="emailTxt" width="100%"/>
	</mx:FormItem>
	
	<mx:FormItem label="Categoria:" width="100%" required="true">
		<mx:ComboBox id="cbCategory" prompt="Selecione uma categoria" dataProvider="{categoryList}" 
			minWidth="180" labelField="name" width="100%"/>
	</mx:FormItem>
	
	<mx:FormHeading label="Situação" fontSize="10"/>
	
	<mx:FormItem label="Situação:" width="100%" required="true" direction="horizontal">
		<mx:RadioButtonGroup id="statusModify"/>
		<mx:RadioButton id="statusAtivo" groupName="statusModify" label="Ativo" value="true"/>
		<mx:RadioButton id="statusBaixado" groupName="statusModify" label="Baixado" value="false"/>
	</mx:FormItem>
	
	<mx:FormItem width="100%" direction="horizontal" horizontalAlign="right">
		<mx:Button label="cancelar" icon="@Embed('assets/icons/delete.png')"  click="PopUpManager.removePopUp(this);"/>
		<mx:Button id="confirmBtn" label="confirmar" icon="@Embed('assets/icons/save.png')" />
	</mx:FormItem>
</mx:Form>
	
</mx:TitleWindow>

Valeu!

Tente colocar o código da linha 41 logo abaixo do if linha 36

Desculpe, estava errado mudei a linha 41 para

Mesmo assim não funciona. O problema é que o length do dataprovider é 1(que é o valor “Selecione uma categoria”), e no combo aparece todas as categorias…

Não sei pq…

eu seto o selectedItem direto, com objeto que quero mostrar e funciona…

Eu tentei setar direto tb, só que o problema é que o combobox está com 1 elemento quando tento setar o objeto, mesmo eu colocando o dataprovider correto, pois na tela ele mostra corretamente.

[code]<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx=“http://www.adobe.com/2006/mxml” creationComplete=“init()” title=“Modifica e-mail” width="600"
showCloseButton=“true” close=“PopUpManager.removePopUp(this);”>

mx:Script
<![CDATA[
import mx.controls.Alert;
import mx.managers.PopUpManager;
import br.com.crtecnologia.sendmail.entity.mailing.Contact;
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;

    [Bindable]
    private var categoryList:ArrayCollection;
    
    public var contact:Contact;
    
    public static const OK:String = "modifyContact_OK";
    
    private function init():void
    {
        PopUpManager.centerPopUp(this);
        listAllCategory();
        nameTxt.text = contact.name;
        emailTxt.text = contact.mail;
        statusModify.selectedValue = contact.status;
        cbCategory.selectedItem = contact.category; // estou setando diretamente o objeto no combobox, mais não funciona...
        /* selectComboBox(cbCategory, contact.getCategoryId()); */
    }
    
    public function selectComboBox(comboBox: ComboBox, id: int): void 
    {
        var dataProvider:ArrayCollection = ArrayCollection(comboBox.dataProvider);
        var selectedIndex: int = 0;
        
        for (var i:int = 0; i < dataProvider.length; i++) {
            if (dataProvider[i].id == id) {
                selectedIndex = i;
                break;
            }
        }
        comboBox.selectedIndex = selectedIndex;
    } 
    
    private function listAllCategory():void
    {
        categoryService.listAllCategory();
    }
    
    private function listAllCategoryResult(event:ResultEvent):void
    {
        categoryList = event.result as ArrayCollection;
    }
]]>

</mx:Script>

<mx:RemoteObject id=“categoryService” destination=“categoryServices”>
<mx:method name=“listAllCategory” result=“listAllCategoryResult(event)”/>
</mx:RemoteObject>

<mx:Form width=“100%”>
<mx:FormHeading label=“Dados do contato” fontSize=“10”/>

<mx:FormItem label="Nome:" width="100%" required="true">
    <mx:TextInput id="nameTxt" width="100%"/>
</mx:FormItem>

<mx:FormItem label="E-mail:" width="100%" required="true">
    <mx:TextInput id="emailTxt" width="100%"/>
</mx:FormItem>

<mx:FormItem label="Categoria:" width="100%" required="true">
    <mx:ComboBox id="cbCategory" prompt="Selecione uma categoria" dataProvider="{categoryList}" 
        minWidth="180" labelField="name" width="100%"/>
</mx:FormItem>

<mx:FormHeading label="Situação" fontSize="10"/>

<mx:FormItem label="Situação:" width="100%" required="true" direction="horizontal">
    <mx:RadioButtonGroup id="statusModify"/>
    <mx:RadioButton id="statusAtivo" groupName="statusModify" label="Ativo" value="true"/>
    <mx:RadioButton id="statusBaixado" groupName="statusModify" label="Baixado" value="false"/>
</mx:FormItem>

<mx:FormItem width="100%" direction="horizontal" horizontalAlign="right">
    <mx:Button label="cancelar" icon="@Embed('assets/icons/delete.png')"  click="PopUpManager.removePopUp(this);"/>
    <mx:Button id="confirmBtn" label="confirmar" icon="@Embed('assets/icons/save.png')" />
</mx:FormItem>

</mx:Form>

</mx:TitleWindow>
[/code]

Agora já vi qual é o problema. Vc seta o data provider depois do indíce. Já tive um problema desses quando eu carregava um cadastro de endereço. Eu setava o combo de estado e de cidade. Só que o dataProvider de cidade era carregado posteriormente, já que é dependente do estado. Para resolver isso extend o combo:

[code]package br.com.nuccitelli.component {
import flash.events.Event;
import mx.binding.utils.BindingUtils;
import mx.utils.ObjectUtil;
import spark.components.DropDownList;

public class DropDowListWithMemory extends DropDownList {
	private var _selectedItemInMemory:Object=null;

	public function DropDowListWithMemory() {
		super();
		BindingUtils.bindSetter(dataProviderHandler,this,[ "dataProvider","length" ]);
	}

	private function dataProviderHandler(obj:Object=null):void {
		if(_selectedItemInMemory) {
			for each(var item:Object in this.dataProvider) {
				if(this.equals(item,_selectedItemInMemory)) {
					this.selectedItem=item;
					break;
				}
			}
		}
	}

	/**
	 * The selectedItemInMemory sets selectedItem in 2 ocasions:
	 * 1) When you set selectedItemInMemory and data provider has an equals object
	 * 2) When dataProvider change and has an object equals to selectedItemInMemory
	 **/
	public function get selectedItemInMemory():Object {
		return _selectedItemInMemory;
	}

	/**
	 * The selectedItemInMemory sets selectedItem in 2 ocasions:
	 * 1) When you set selectedItemInMemory and data provider has an equals object
	 * 2) When dataProvider change and has an object equals to selectedItemInMemory
	 **/
	public function set selectedItemInMemory(value:Object):void {
		_selectedItemInMemory=value;
		dataProviderHandler();
	}

	private function equals(item:Object,item2:Object):Boolean {
		return ObjectUtil.compare(item,item2)==0;
	}
}

}[/code]

Sete o selectecItemInMemory para fazer o que vc quer. Quando vc seta esse intem, ele procura no dataProvider e seta o item de acordo, assim como acontece no comum. Contudo, toda vez que vc altera o dataProvider, ele confere para ver se o mesmo contem o selecteItemInMemory. Se tiver, ele seta esse campo.
Eu fiz a DropDownList que uso como combo no Flex 4. Se vc estiver usando Flex 3, subistitua para Combo para funfar.

Precisando de um curso Flex, de uma olhada na Nuccitec.

Tb vou ver se coloco esse componente no blog da empresa, pois não é a primeira vez que vejo essa dúvida por aqui.

[]s

Passar essas linhas:

nameTxt.text = contact.name;  
emailTxt.text = contact.mail;  
statusModify.selectedValue = contact.status;  
cbCategory.selectedItem = contact.category;

Para dentro do método "listAllCategoryResult"
Já não iria resolver?

[quote=Ygor]Passar essas linhas:

nameTxt.text = contact.name;  
emailTxt.text = contact.mail;  
statusModify.selectedValue = contact.status;  
cbCategory.selectedItem = contact.category;

Para dentro do método "listAllCategoryResult"
Já não iria resolver?[/quote]

Tentei dessa maneira e tb não funcionou. Não entendo pq, eu estou recebendo a lista antes e depois setando o valor.

renzonuccitelli, também fiz o componente que você disse e não funfou, to ficando louco com isso…

veja o código:

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()" title="Modifica e-mail" width="600"
	showCloseButton="true" close="PopUpManager.removePopUp(this);" xmlns:components="br.com.crtecnologia.sendmail.components.*">

<mx:Script>
	<![CDATA[
		import mx.controls.Alert;
		import mx.managers.PopUpManager;
		import br.com.crtecnologia.sendmail.entity.mailing.Contact;
		import mx.collections.ArrayCollection;
		import mx.rpc.events.ResultEvent;
		
		[Bindable]
		private var categoryList:ArrayCollection;
		
		[Bindable]
		public var contact:Contact;
		
		public static const OK:String = "modifyContact_OK";
		
		private function init():void
		{
			PopUpManager.centerPopUp(this);
			listAllCategory();
			nameTxt.text = contact.name;
			emailTxt.text = contact.mail;
			statusModify.selectedValue = contact.status;
			cbCategory.selectedItemInMemory(contact.category);
		}
		
		private function listAllCategory():void
		{
			categoryService.listAllCategory();
		}
		
		private function listAllCategoryResult(event:ResultEvent):void
		{
			categoryList = event.result as ArrayCollection;
		}
	]]>
</mx:Script>

<mx:RemoteObject id="categoryService" destination="categoryServices">
	<mx:method name="listAllCategory" result="listAllCategoryResult(event)"/>
</mx:RemoteObject>

<mx:Form width="100%">
	<mx:FormHeading label="Dados do contato" fontSize="10"/>

	<mx:FormItem label="Nome:" width="100%" required="true">
		<mx:TextInput id="nameTxt" width="100%"/>
	</mx:FormItem>

	<mx:FormItem label="E-mail:" width="100%" required="true">
		<mx:TextInput id="emailTxt" width="100%"/>
	</mx:FormItem>
	
	<mx:FormItem label="Categoria:" width="100%" required="true">
		<components:DropDowListWithMemory id="cbCategory" prompt="Selecione uma categoria" dataProvider="{categoryList}" 
			minWidth="180" labelField="name" width="100%"/>
	</mx:FormItem>
	
	<mx:FormHeading label="Situação" fontSize="10"/>
	
	<mx:FormItem label="Situação:" width="100%" required="true" direction="horizontal">
		<mx:RadioButtonGroup id="statusModify"/>
		<mx:RadioButton id="statusAtivo" groupName="statusModify" label="Ativo" value="true"/>
		<mx:RadioButton id="statusBaixado" groupName="statusModify" label="Baixado" value="false"/>
	</mx:FormItem>
	
	<mx:FormItem width="100%" direction="horizontal" horizontalAlign="right">
		<mx:Button label="cancelar" icon="@Embed('assets/icons/delete.png')"  click="PopUpManager.removePopUp(this);"/>
		<mx:Button id="confirmBtn" label="confirmar" icon="@Embed('assets/icons/save.png')" />
	</mx:FormItem>
</mx:Form>
	
</mx:TitleWindow>

Não sabia que dava pra usar o método set assim: cbCategory.selectedItemInMemory(contact.category). O que eu faço é sempre assim:cbCategory.selectedItemInMemory=contact.category. Debugue o método dataProviderHandler para conferir se realmente vc está passando o obj correto para o selected item in memory. Além disso, debugando vc vai poder conferir melhor a lógica, podendo verificar onde está o erro.

[]s

Cara, funcionou do jeito que você falou…

Agradeço pela ajuda.

De nada. Agradeço se puder divulgar meu curso se souber de pessoas interessadas em aprender Flex/Java :slight_smile:

Vou colocar uns posts de Flex bacanas no blog da empresa. Tb já tem alguns legais, como validação de CPF e CBPJ, de uma conferida: Blog Nuccitec.

[]s

Coloque sim, vai ser muito útil e com certeza irá atrair muitas pessoas para os cursos.

Se souber de alguém falo de você.

Abraços!

Fiz o post e coloquei o código unitário também, basta conferir aqui.

[]s