ItemRenderer

Eai pessoal,

Uma duvida aqui, se alguem souber responder, manda ve ai…
tenho um datagrid com suas colunas com um TextInput…

tem como eu mudar a cor de 1 textInput especifico, quando o item for editado,
a principal duvida é como alterar a cor do TextInput mesmo… depois que o grid foi criado…

abraço
vlws desde já ;D

ps: pelo ItemEdit tem como pegar o TextInput especifico e alterar sua cor? =P

Bom dia Bruno,

Existem várias maneiras de fazer isso, mas uma das mais simples é colocar essa regra no seu ItemRenderer. Ex:

	<mx:DataGrid dataProvider="{dp}">
		<mx:itemRenderer>
			<mx:Component>

				<mx:TextInput 
					change="onChange(event)">

					<mx:Script>
						<![CDATA[
							private function onChange(event:Event):void
							{
								this.setStyle('backgroundColor', 0xFFFF00);
							}
						]]>
					</mx:Script>

				</mx:TextInput>

			</mx:Component>
		</mx:itemRenderer>
	</mx:DataGrid>

Ps: Não declare o ItemRenderer inline assim, faça numa classe separada, fiz só pra ficar mais fácil de mostrar.

[]s

Não querendo atrapalhar o tópico, mas…
André, por que você diz que sempre devo fazer numa classe separada (e ‘colocar’ em outra usando ou ClassFactory ou setando no itemRenderer)? Tem alguma diferença de performance, é só o código que fica mais organizado ou é porque ele vira meio ‘genérico’ e dá pra usar ele em vários outros lugares?

Acho que não tem muita diferença em performance não, André. Eu falo por questão de organização e reaproveitamento mesmo. Sem contar que o código fica bem confuso se você ficar declarando varios componentes dentro de um mesmo arquivo, fica mais difícil de entender.

[]s

hehe, é o meu já esta separado, já tentei fazer dessa forma até…
mais no dia que tentei não consegui…

hoje anoite… eu vou testar denovo…

vlwss …

Detalhe: to criando minhas colunas dinamicamente também…

ex:

tenho meu dataGrid no mxml…

e depois preciso de colunas adicionais que variam… dependendo do mes… que tem os itemrenderer

por questão de performance…
é melhor criar assim, ou criar ela toda no AS3 ??

Eu criaria elas no AS mesmo, como imagino que você já esteja fazendo. Aí teria meu renderer em uma classe separada e, na hora de criar a coluna dinamicamente, eu faria algo assim:

var column:DataGridColumn = new DataGridColumn();
column.itemRenderer = new ClassFactory(MyItemRenderer);

A unica dica de performance seria para você tomar cuidado com o ItemRenderer. Tente deixar ele o mais leve possível, pois DataGrid com muitos renderers podem se tornar pesados se eles não forem bem programados.

[]s

hmm intendi, Andre…

estou fazendo em AS sim… mais supondo…

Tenho meu ItemRenderer um TextInput…


package
{
	import mx.controls.TextInput;

	public class MyItemRenderer extends TextInput
	{
		public function MyItemRenderer ()
		{
			super();
		}
		
	}
}

ai no meu … mxml…

tenho


<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*">
	
	
	
	
	<mx:DataGrid x="299" y="139">
		<mx:columns>
			<mx:DataGridColumn headerText="Column 1" dataField="col1"/>
			<mx:DataGridColumn headerText="Column 2" dataField="col2"/>
			<mx:DataGridColumn headerText="Column 3" dataField="col3"/>
		</mx:columns>
	</mx:DataGrid>
	
	
	
</mx:Application>

correto?

e tipo…

tenho uma função… que cria as colunas que eu preciso… Renderizadas…


public static function crieColuna(headerText:String, dataField:String, widht:uint, 
			textAlign:String, editable:Boolean = false):DataGridColumn{
 
			var novaColuna:DataGridColumn = new DataGridColumn();
			novaColuna.headerText = headerText;
			novaColuna.dataField = dataField;
			novaColuna.width = widht;
			novaColuna.setStyle("textAlign",textAlign);
			novaColuna.editable = editable;
			novaColuna.itemRenderer = new ClassFactory(TextInputPerson);			
			return novaColuna;
		}

O ambiente é esse então… agora vem a pergunta hehe…

se eu colocar um listener…


package
{
	import mx.controls.TextInput;

	public class MyItemRenderer extends TextInput
	{
		public function MyItemRenderer ()
		{
			super();
                         this.addEventListener(Event.CHANGE, onChange) //isso aqui não funfa huaeheuh

		}
		
	}

        public function onChange(event:Event){
                   setStyle("backgroundColor", "yellow");
        }




}

isso tem que acontecer em um textInput, quando for alterado o dado de um textInput especifico saka?
provavelmente to esquecendo o dispach, bom… é isso ai…
se alguem souber a solução… ahueueh
Se os ninja do flex ai souber a solução fico muito feliz

[]'s

Só uma coisa.

Esse é seu construtor. Mas o construtor não tem que ser do mesmo nome da classe? Em AS é diferente de Java isso?

Outra coisa. Se eu estiver errado em cima, tenta criar um método pra você chamar o event (ou melhor, pra você adicionar ele, em vez de adicionar no construtor).

pow, claro que tem que ser sim rsrs…
fiz o exemplim aqui na hora…
malz…

então acho que o problema não é nem isso cara, o listener acho que não tem problema ficar no construtor…

acho que tenho que dar um dispach em algum lugar… só não sei aonde ainda…rsrs

[]s

vlwss ai andré

Opa Bruno, criei a seguinte aplicação de teste e está tudo okay:

Teste.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

	<mx:Script>
		<![CDATA[
			import mx.controls.dataGridClasses.DataGridColumn;
			import mx.collections.ArrayCollection;

			[Bindable]
			private var dp:ArrayCollection = new ArrayCollection([
						{c1: "1", c2: "2", c3: "3"},
						{c1: "4", c2: "5", c3: "6"},
						{c1: "7", c2: "8", c3: "9"},
						{c1: "10", c2: "11", c3: "12"}
					]);

			private function addCol():void
			{
				var column:DataGridColumn = new DataGridColumn();
				var cols:Array = dg.columns;

				column.dataField = "c3";
				column.itemRenderer = new ClassFactory(MyItemRenderer)
				cols.push(column);

				dg.columns = cols;
			}
		]]>
	</mx:Script>

	<mx:DataGrid id="dg" dataProvider="{dp}" width="350">
		<mx:columns>
			<mx:DataGridColumn dataField="c1" itemRenderer="MyItemRenderer"/>
			<mx:DataGridColumn dataField="c2" itemRenderer="MyItemRenderer"/>
		</mx:columns>
	</mx:DataGrid>

	<mx:Button label="Add col3"
		click="addCol()"/>

</mx:Application>

MyItemRenderer.as

package
{
	import flash.events.Event;
	import mx.controls.TextInput;

	public class MyItemRenderer extends TextInput
	{
		public function MyItemRenderer()
		{
			super();

			this.addEventListener(Event.CHANGE, onChange);
		}

		private function onChange(event:Event):void
		{
			this.setStyle("backgroundColor", 0xFFFF00);
		}

	}
}

Faça um teste para ver se resolve.

[]s

hehe, eu tinha feito isso, achei que tava esquecendo alguma coisa…

tipo André, o itemRenderer devia fazer isso, sempre que tivesse alteração correto?
só que ele faz “as vezes” eu não sei o motivo, mais se eu ficar alterando alterando o grid, de vez enquando
ele entra e altera a cor, -__-’

tem idéia do por que disto?

Hummm, estranho… Mas deve ser algo referente ao seu projeto, pois nesse exemplo que fiz não acontece isso.

Você está alterando o dataProvider por algum motivo? Ou dando um myDataProvider.refresh() ou algo assim?
Isso faria ele desenhar os renderers novamente e perderia a cor.

Concerteza é algo no projeto mesmo, eu também tinha feito isso fora do projeto e funcionou normalmente…
to usando PureMVC e o BlazeDS…

mais depois vou fazer uns testes adicionais… tipo

não estou alterando o provider não…

tipo…

eu altero 1 celula ele nao faz nda, ai altero outra não faz nada, ai altero outra e ele muda a acor… sacou?

ai dps não altera, se eu fica alterando celula por celula, as vezes ele altera… rsrsrs

coisa do demon msm…uaehueha

mais valeu ai André !
não parei pra ficar debugando isso infinitamente até ver o que ta acontecendo ainda não huaeheuh.

Eai André,

Deu certo agora, o CHANGE não tava funcionando legal… ai eu fiz com FocusOut e ta fico tudo legal…
rsrs

vlws pela ajuda…

Abraçow

Bruno.

Tome cuidado pois o FocusOut pode acontecer sem que o valor do textInput tenha sido alterado, e pelo que eu entendi você precisa trocar o style somente quando o texto é alterado.

hehe to ligado thiagoo!
eh que o Change nao tava se comportando legal não sei o motivo…

as vezes ele chamava o metodo e as vezes não saka

ai to usando uma OOG com focus in e focus out rsrs =P

pra chegar isso…

Eu revivendo o tópico aqui…

como faço pra mim da um “refresh” no datagrid, pra ele tirar os Renderer que foram alterados (e no caso estão em amarelos)?

rsrsrs

Olá brunno,

Sobrescreva o setter do atributo data que vai funcionar corretamente. Sem gambi de focusIn e focusOut.

Quanto ao DG, você dará um refresh no arraycollection dele. Procure sobre “array filtering flex”.

Pode crer AUser, tava dando uma conversada com um amigo…
e ele falou pra dar um set do data mesmo… usando uma flag pra especificar…
se foi alterado ou não…

vou testar fazer dessa forma…
igual estsava tentando fazer, não tem como pelo que intendi …
por que o itemRenderer é reaproveitado…

[quote=andre.gil]Opa Bruno, criei a seguinte aplicação de teste e está tudo okay:

Teste.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

	<mx:Script>
		<![CDATA[
			import mx.controls.dataGridClasses.DataGridColumn;
			import mx.collections.ArrayCollection;

			[Bindable]
			private var dp:ArrayCollection = new ArrayCollection([
						{c1: "1", c2: "2", c3: "3"},
						{c1: "4", c2: "5", c3: "6"},
						{c1: "7", c2: "8", c3: "9"},
						{c1: "10", c2: "11", c3: "12"}
					]);

			private function addCol():void
			{
				var column:DataGridColumn = new DataGridColumn();
				var cols:Array = dg.columns;

				column.dataField = "c3";
				column.itemRenderer = new ClassFactory(MyItemRenderer)
				cols.push(column);

				dg.columns = cols;
			}
		]]>
	</mx:Script>

	<mx:DataGrid id="dg" dataProvider="{dp}" width="350">
		<mx:columns>
			<mx:DataGridColumn dataField="c1" itemRenderer="MyItemRenderer"/>
			<mx:DataGridColumn dataField="c2" itemRenderer="MyItemRenderer"/>
		</mx:columns>
	</mx:DataGrid>

	<mx:Button label="Add col3"
		click="addCol()"/>

</mx:Application>

MyItemRenderer.as

package
{
	import flash.events.Event;
	import mx.controls.TextInput;

	public class MyItemRenderer extends TextInput
	{
		public function MyItemRenderer()
		{
			super();

			this.addEventListener(Event.CHANGE, onChange);
		}

		private function onChange(event:Event):void
		{
			this.setStyle("backgroundColor", 0xFFFF00);
		}

	}
}

Faça um teste para ver se resolve.

[]s[/quote]

Minha vez de dar vida novamente ao tópico. rsrs
Pessoal, boa tarde!

Neste caso você só tem um textInput.
A minha dúvida é que eu preciso de um textInput ou combo ou check.
Como fazer?
abs