kapak 0 Denunciar post Postado Janeiro 28, 2005 Olá colegas, como fazer para não inserir ítens duplicados num ComboBox.Num TStringList qdo se ativa a propriedade Sorted e deixa a propriedade Duplicates = Dupignore, ele não insere ítens duplicados.O TComboBox.Items descende de TStrings e não possui a propriedade Duplicates.Já tentei castear TStringList(TComboBox.Items).Duplicates = Dupignore, mas mesmo assim ele insere ítens em duplicidade; então atualmente utilizo um TStringList e depois assinalo TComboBox.Items p/ o TStringList.Alguém saberia como fazer isto diretamente no ComboBox ?Abraços !!! Compartilhar este post Link para o post Compartilhar em outros sites
InuTaishou 0 Denunciar post Postado Janeiro 28, 2005 Colega, veja: Var wItem : String;Begin wItem := 'Item01'; If ComboBox1.Items.IndexOf( wItem ) >= 0 Then ShowMessage( 'Já existe!' ) Else ComboBox1.Items.Add( wItem );End; Compartilhar este post Link para o post Compartilhar em outros sites
kapak 0 Denunciar post Postado Janeiro 28, 2005 Olá, obrigado pela resposta. Olha, sem querer criticar, mas confesso que apanhei um pouco com isso e a minha primeira solução foi o IndexOf. você pode fazer um teste, e verá que a performance cai muitíssimo em relação ao TStringList e depois o Assign. Compartilhar este post Link para o post Compartilhar em outros sites
Massuda 0 Denunciar post Postado Janeiro 28, 2005 [...] verá que a performance cai muitíssimo em relação ao TStringList e depois o Assign.Você tem razão. TStrings.IndexOf é uma rotina lenta: ela faz busca linear na lista de strings e, por causa disso, no caso da string não estar duplicada (o que provavelmente acontece na maior parte das vezes), ela percorre toda a lista a cada inserção. Por outro lado, num TStringList ordenado, TStringList.Add usa busca binária, o que faz a busca por strings duplicadas ser extremamente rápida. Note que a busca binária é utilizada apenas se a lista for ordenada. Compartilhar este post Link para o post Compartilhar em outros sites
Beppe 0 Denunciar post Postado Janeiro 28, 2005 Realmente a caixa de combinação do Windows foi idiotamente projetada. Você terá que fazer isto por si mesmo. Mantenha uma TStringList, L, que tem o código necessário para a checagem. procedure TForm1.Button1Click(Sender: TObject);var S: String;begin S := Edit1.Text; ComboBox1.Items.Insert(L.Add(S), S);end;procedure TForm1.FormCreate(Sender: TObject);begin L := TStringList.Create; L.Sorted := True; L.Duplicates := dupError;end; O problema, como esta solução simples é que há duas listas que contém exatamente a mesma coisa. Enquanto a caixa combo não permite ítems virtuais, a StringList gerencia sua própria lista interna apenas. Se você deseja evitar as cópias em run-time, ou reimplemente busca binária e inserção na caixa combo(como é feito na TStringList em Classes.pas), ou use uma lista owner draw, que pinta a partir da lista L. A primeira opção dá mais trabalho, mas seria mais eficiente, porque a cambo ainda mantém uma lista interna(não é virtual). Compartilhar este post Link para o post Compartilhar em outros sites
kapak 0 Denunciar post Postado Janeiro 29, 2005 Olá Beppe, bom atualmente faço o seguinte:1-Crio um TStringList c/ Sorted, not CaseSensitive e Duplicates=DupIgnore.2-Vou adicionando tudo lá em run-time.3-No término das adiçoes executo: TComboBox.Items.Assign(TStringList).4-Libero a TStringList.Com isto obtive uma performance bem superior à do IndexOf do combo.Pode não ser o método ideal, mas a performance agora é satisfatória.Só que ficou uma dúvida:Pq quando eu libero a TStringList, não afeta nos ítens da combo?Eu não estaria liberando a mesma área de memória da TComboBox.Items ? Compartilhar este post Link para o post Compartilhar em outros sites
kapak 0 Denunciar post Postado Janeiro 29, 2005 Acho que o Assign realoca outra área de memória e faz uma cópia dos dados originais.Será isto ? :huh: Compartilhar este post Link para o post Compartilhar em outros sites
Beppe 0 Denunciar post Postado Janeiro 29, 2005 Acho que o Assign realoca outra área de memória e faz uma cópia dos dados originais.Será isto ? :huh:Exatamente. Tanto a lista em TStringList bem como da combo são listas internas, cada uma com sua cópia.A maneira que está fazendo atualmente com certeza deve ser a melhor para o seu caso, já que você não parece precisar manter as duas listas ao mesmo tempo. Há um custo para a copia que Assign faz, mas dificilmente será significativo. Compartilhar este post Link para o post Compartilhar em outros sites
InuTaishou 0 Denunciar post Postado Janeiro 29, 2005 Deve haver uma maneira de "dizer" ao ComboBox que o Items dele será a TStringList L, não?[]'s, Compartilhar este post Link para o post Compartilhar em outros sites
Beppe 0 Denunciar post Postado Janeiro 29, 2005 Deve haver uma maneira de "dizer" ao ComboBox que o Items dele será a TStringList L, não?[]'s, Não, pq se o programador tivesse acesso a lista interna, que provavelmente não contém apenas strings, da combo(pq teria acesso, se a lista pudesse ser Assign'ada), ele poderia desestabilizar o sistema, pq os elementos gráficos rodam no kernel.Talvez haja uma maneira de manter os item ordenados dentro da combo mesmo, mas o Delphi não exporta esta facilidade. Mesmo que haja, precisaria deste suporte em todos os Windows, e os mais antigos, 95 e 98 não devem ter. Compartilhar este post Link para o post Compartilhar em outros sites
InuTaishou 0 Denunciar post Postado Janeiro 29, 2005 Hmmm... Certo... Entendi... E agradeço muito a explicação![]'s, Compartilhar este post Link para o post Compartilhar em outros sites