TreeView Editável.. É possível??
Bom dia Pessoal,
Minha TreeView está assim:
Eu tava querendo saber se tem jeito do usuário escrever nessa treeView, mais precisamente no lugar do [b:e6b2e6873d]X[/b:e6b2e6873d]. Ou se tem algum componente melhor pra fazer isto....
Qualquer Ajuda é muito bem vinda...
Lucas!
Minha TreeView está assim:
Texto |-Igual |- x
Eu tava querendo saber se tem jeito do usuário escrever nessa treeView, mais precisamente no lugar do [b:e6b2e6873d]X[/b:e6b2e6873d]. Ou se tem algum componente melhor pra fazer isto....
Qualquer Ajuda é muito bem vinda...
Lucas!
Lucas Silva
Curtidas 0
Respostas
Vinicius2k
18/06/2004
Lucas,
Escrever na TreeView é relativamente simples, mas o que eu não entendi é se vai haver interação do usuário em informar qual item ele quer editar (através de seleção)...
Se sim, por exemplo :
Se não vc precisará armazenar em uma variável o AbsoluteIndex do node que vc quer editar e aplicar no Items[xxx] da rotina acima...
É isso q vc precisa?
T+
Escrever na TreeView é relativamente simples, mas o que eu não entendi é se vai haver interação do usuário em informar qual item ele quer editar (através de seleção)...
Se sim, por exemplo :
procedure TForm1.Button1Click(Sender: TObject); begin TreeView1.Items[TreeView1.Selected.AbsoluteIndex].Text:= Edit1.Text; end;
Se não vc precisará armazenar em uma variável o AbsoluteIndex do node que vc quer editar e aplicar no Items[xxx] da rotina acima...
É isso q vc precisa?
T+
GOSTEI 0
Lucas Silva
18/06/2004
2k,
O que eu estou querendo é o usuario clicar e alterar um dado na treeview,
se possível escrevendo nela mesmo....
Vamos supor que eu tenha a treeview:
Tem jeito de clicar na palavra [b:22f9e6eb61]Lucas[/b:22f9e6eb61], e sair editando???
Não sei se isso é possível...
O que eu estou querendo é o usuario clicar e alterar um dado na treeview,
se possível escrevendo nela mesmo....
Vamos supor que eu tenha a treeview:
Nome |- Igual |- Lucas
Tem jeito de clicar na palavra [b:22f9e6eb61]Lucas[/b:22f9e6eb61], e sair editando???
Não sei se isso é possível...
GOSTEI 0
Vinicius2k
18/06/2004
Entendi... bem, com o TreeView convencional não conheço... e me arriscaria a dizer q não tem jeito, mas posso estar enganado...
Acho que seria melhor para esta situação vc procurar por algum componente de 3º que tenha esta funcionalidade...
T+
Acho que seria melhor para esta situação vc procurar por algum componente de 3º que tenha esta funcionalidade...
T+
GOSTEI 0
Lucas Silva
18/06/2004
Entendi... bem, com o TreeView convencional não conheço... e me arriscaria a dizer q não tem jeito, mas posso estar enganado...
Acho que seria melhor para esta situação vc procurar por algum componente de 3º que tenha esta funcionalidade...
T+
Valeu...
Vou dar uma procurada aqui...
GOSTEI 0
Nildo
18/06/2004
Lucas, use o método:
TreeView1.Selected.EditText;
TreeView1.Selected.EditText;
GOSTEI 0
Vinicius2k
18/06/2004
Lucas, use o método:
TreeView1.Selected.EditText;
:oops: comprovado que eu estava enganado...
pensando bem, seria muito estranho a TreeView não ter este recurso mesmo...
GOSTEI 0
Xanatos
18/06/2004
Bom...nao precisa de mudar nada pra editar é só mudar a propriedade readonly para false! e voce mudar como um arquivo ou pasta do windows!
GOSTEI 0
Michael
18/06/2004
Olá amigo Lucas!
O componente TTreeView tem a propriedade ReadOnly que define se os labels dos seus itens serão editáveis ou não. Se esta propriedade for setada para false, então quando o usuário der um clique sobre um ítem selecionado da lista o Windows permitirá a sua edição. Uma desvantagem decorrente deste procedimento é que todos os ítens poderão ser alterados pelo usuário. Em alguns casos é necessário que apenas determinados itens sejam editáveis, e outros não. Infelizmente os objetos TTreeNode não tem uma propriedade ReadOnly individual, o que facilitaria em muito o trabalho. Mas como pessoalmente o Delphi é a ferramenta mais flexivél que existe, nada o que um pouco de código não resolva não é?
Imagine que você tenha o seguinte TreeView:
Apenas o nome ´Michael Benford´ deveria ser editável, e não os outros. Para que isso seja possível, basta adicionar no evento OnClick do TreeView:
O ´macete´ aqui é utilizar a propriedade Level do TTreeNode para saber em qual nível nosso ítem está localizado. Como a contagem começa de 0, então nosso nome está no nível 3. Existem outras maneiras de se obter o mesmo resultado, como utilizar a propriedade ImageIndex do TreeNode, caso você defina uma imagem personalizada para esse nível. Você ainda poderia utilizar também outra propriedade, HasChildren, que informa se o ítem tem ´filhos´ ou não. Assim, somente os ítens do último nível serão editados. Nosso exemplo ficaria assim:
Esta abordagem talvez seja a mais prática, mas somente, como já dito, os últimos ítens serão editáveis. A vantagem é que você não terá que se preocupar em contar os nívels (Levels) de cada ítem.
Espero ter ajudado amigo! Qualquer dúvida, estamos aí.
Abraços!
O componente TTreeView tem a propriedade ReadOnly que define se os labels dos seus itens serão editáveis ou não. Se esta propriedade for setada para false, então quando o usuário der um clique sobre um ítem selecionado da lista o Windows permitirá a sua edição. Uma desvantagem decorrente deste procedimento é que todos os ítens poderão ser alterados pelo usuário. Em alguns casos é necessário que apenas determinados itens sejam editáveis, e outros não. Infelizmente os objetos TTreeNode não tem uma propriedade ReadOnly individual, o que facilitaria em muito o trabalho. Mas como pessoalmente o Delphi é a ferramenta mais flexivél que existe, nada o que um pouco de código não resolva não é?
Imagine que você tenha o seguinte TreeView:
Cadastro |- Dados pessoais |- Nome |- Michael Benford
Apenas o nome ´Michael Benford´ deveria ser editável, e não os outros. Para que isso seja possível, basta adicionar no evento OnClick do TreeView:
procedure TForm1.TreeView1Click(Sender: TObject);
begin
{ Evita que seja gerado um erro de Access Violation se nada foi selecionado }
if TreeView1.Selected = nil then exit;
TreeView1.ReadOnly := not (TreeView1.Selected.Level = 3);
end;
O ´macete´ aqui é utilizar a propriedade Level do TTreeNode para saber em qual nível nosso ítem está localizado. Como a contagem começa de 0, então nosso nome está no nível 3. Existem outras maneiras de se obter o mesmo resultado, como utilizar a propriedade ImageIndex do TreeNode, caso você defina uma imagem personalizada para esse nível. Você ainda poderia utilizar também outra propriedade, HasChildren, que informa se o ítem tem ´filhos´ ou não. Assim, somente os ítens do último nível serão editados. Nosso exemplo ficaria assim:
procedure TForm1.TreeView1Click(Sender: TObject);
begin
{ Evita que seja gerado um erro de Access Violation se nada foi selecionado }
if TreeView1.Selected = nil then exit;
TreeView1.ReadOnly := TreeView1.Selected.HasChildren;
end;
Esta abordagem talvez seja a mais prática, mas somente, como já dito, os últimos ítens serão editáveis. A vantagem é que você não terá que se preocupar em contar os nívels (Levels) de cada ítem.
Espero ter ajudado amigo! Qualquer dúvida, estamos aí.
Abraços!
GOSTEI 0
Lucas Silva
18/06/2004
Ótimo pessoal...
Funcionou legal...
Só mais uma dúvida aqui.
Com este código quando clico no nivel 2 do TV ele deixa para a edição.
Quando digito alguma coisa e clico em outro TreeNode ele não sai (fica com o foco só no TreeNode editável (de nível 2) ), a não ser que eu dê um enter no TreeNode de nível 2, e depois clique em outro TreeNode;
Alguem já passou por isto??
Lucas!
Funcionou legal...
Só mais uma dúvida aqui.
procedure TForm1.TreeView1Click(Sender: TObject);
begin
{ Evita que seja gerado um erro de Access Violation se nada foi selecionado }
if TreeView1.Selected = nil then exit;
if TreeView1.Selected.Level = 2 then
TreeView1.Selected.EditText;
end;Com este código quando clico no nivel 2 do TV ele deixa para a edição.
Quando digito alguma coisa e clico em outro TreeNode ele não sai (fica com o foco só no TreeNode editável (de nível 2) ), a não ser que eu dê um enter no TreeNode de nível 2, e depois clique em outro TreeNode;
Alguem já passou por isto??
Lucas!
GOSTEI 0
Vinicius2k
18/06/2004
Lucas,
o que o colega xanatos sugeriu eu sabia, mas imaginei que vc não quisesse tornar todos os ítens editáveis...
bem, então pode-se aliar a isso a ténica do colega michel, mas talvez de uma forma mais simples...
sem usar o OnClick... seria o método convencional do windows de um click depois outro para entrar em edição (não duplo)... vc protegeria o nível que pode ser editado no evento OnEditing, dessa forma, por exemplo:
também pode usar a leitura da propriedade HasChildrens para permitir a edição apenas de quem não tem filhos, ou seja, o último...
creio que ficaria sem este problema que vc está enfrentando agora...
T+
o que o colega xanatos sugeriu eu sabia, mas imaginei que vc não quisesse tornar todos os ítens editáveis...
bem, então pode-se aliar a isso a ténica do colega michel, mas talvez de uma forma mais simples...
sem usar o OnClick... seria o método convencional do windows de um click depois outro para entrar em edição (não duplo)... vc protegeria o nível que pode ser editado no evento OnEditing, dessa forma, por exemplo:
procedure TForm1.TreeView1Editing(Sender: TObject; Node: TTreeNode; var AllowEdit: Boolean); begin if Node.Level < 2 then AllowEdit:= False; //só permite edição no level 3 end;
também pode usar a leitura da propriedade HasChildrens para permitir a edição apenas de quem não tem filhos, ou seja, o último...
creio que ficaria sem este problema que vc está enfrentando agora...
T+
GOSTEI 0
Xanatos
18/06/2004
Ou voce pode usar o ImageIndex como se fosse uma tag e no evento onEditing!
8)
if Node.ImageIndex <> 1 then AllowEdit:= false;
8)
GOSTEI 0
Lucas Silva
18/06/2004
Gostaria que quando o usuário abrisse o Node ele já viria em codições de edição.
Este código que você me passou ai 2k, tem um problema (não é bem um problema), o usuário tem que abrir o node, clicar em cima dele 2 vezes, e ai sim ele abre para edição...
Teria jeito que resolver isto?
Este código que você me passou ai 2k, tem um problema (não é bem um problema), o usuário tem que abrir o node, clicar em cima dele 2 vezes, e ai sim ele abre para edição...
Teria jeito que resolver isto?
GOSTEI 0
Michael
18/06/2004
Para fazer o que você quer precisamos salvar o item que está selecionado e então verificar no momento da edição se ele não foi o último membro da TreeView que foi modificado: Eis o procedimento adequado para o seu propósito Lucas:
Era assim que você queria que funcionasse?
Ao amigo Vinicius2k: meu nome é Michael, e não Michel! ;-)
Abraços!
procedure TForm1.TreeView1Click(Sender: TObject);
{$J+}
const UltimoItemEditado : TTreeNode = nil;
{$J-}
begin
{ Evita que seja gerado um erro de Access Violation se nada foi selecionado }
if TreeView1.Selected = nil then exit;
{ Permite a edição apenas se o item selecionado estiver no nivel 2 }
TreeView1.ReadOnly := not (TreeView1.Selected.Level = 2);
if not TreeView1.ReadOnly and (TreeView1.Selected <> UltimoItemEditado) then
begin
UltimoItemEditado := TreeView1.Selected;
TreeView1.Selected.EditText;
end;
end;
Era assim que você queria que funcionasse?
Ao amigo Vinicius2k: meu nome é Michael, e não Michel! ;-)
Abraços!
GOSTEI 0
Lucas Silva
18/06/2004
Funcionou sim.
Agora só falta alguns ajustes aqui..
Qual é a função dos [b:cb97f79fec]{$J+} [/b:cb97f79fec]e [b:cb97f79fec]{$J-}[/b:cb97f79fec]
Notei que se não colocar dá um erro de código.
Agora só falta alguns ajustes aqui..
Qual é a função dos [b:cb97f79fec]{$J+} [/b:cb97f79fec]e [b:cb97f79fec]{$J-}[/b:cb97f79fec]
{$J+}
const UltimoItemEditado : TTreeNode = nil;
{$J-} Notei que se não colocar dá um erro de código.
GOSTEI 0
Nildo
18/06/2004
voce quer editar com condição? é facil...
no evento OnEditing você coloca assim:
AllowEdit := (Condicao);
E você pode usar o objeto NODE deste evento. Por exemplo:
AllowEdit := ( Node.text = ´tal´ );
no evento OnEditing você coloca assim:
AllowEdit := (Condicao);
E você pode usar o objeto NODE deste evento. Por exemplo:
AllowEdit := ( Node.text = ´tal´ );
GOSTEI 0
Lucas Silva
18/06/2004
voce quer editar com condição? é facil...
no evento OnEditing você coloca assim:
AllowEdit := (Condicao);
E você pode usar o objeto NODE deste evento. Por exemplo:
AllowEdit := ( Node.text = ´tal´ );
Tranquilo nildo, já está funcionando legal..... Valeu pela dica...
:lol:
Eu gostaria de saber qual função dos [b:d95e6bfcd5]{$J+}[/b:d95e6bfcd5] e [b:d95e6bfcd5]{$J-} [/b:d95e6bfcd5]?
GOSTEI 0
Michael
18/06/2004
Que bom que pude ajudar Lucas!
A diretiva de compilação {$J} serve para ativar/desativar o uso de constantes tipadas. A partir do Delphi 6 não é mais possível alterar o valor de uma constante por padrão, apenas utilizar seu conteúdo. Com essas diretivas você ativa esta utilização. Eu utilizei uma constante para manter a variável dentro do procedimento Click da TreeView. Você poderia entretanto criar uma variável global, ou definir um campo do objeto do formulário principal e fazer o mesmo. Para mais informações sobre constantes consulte [url]http://www.clubedelphi.com.br/artigos/Consttip.html[/url]. Se você não colocar essas diretivas no código em questão, o Delphi irá gerar um erro dizendo que você não pode atribuir um valor a uma constante.
Analisando o seu problema, eu percebi duas coisas que devem ser levadas em consideração. Vamos a elas:
1. Utilizar a propriedade Level para definir quais itens são editáveis pode não ser uma maneira prática de localizar tais itens, pois se você futuramente colocá-los um nível abaixo, ou acima, você terá que retornar ao código e alterar o valor de ´Level´ para a nova posição do item. Para contornar isso, você pode fazer o seguinte: O objeto TTreeNode não tem a propriedade Tag, que serviria como uma luva aqui. Porém, existem outras como StateIndex, SelectedIndex e OverlayIndex. A menos que você utilize-as todas em seu aplicativo, você poderia definir um valor de edição, como 1 por exemplo, para alguma delas e assim definir qual ítem é editável. Ficaria muito mais prático lidar com edições na TreeView desta forma,
2. O último código que lhe passei permite apenas a edição automática do ítem quando o usuário clica sobre ele. Porém, se os usuários de seu programa utilizarem o teclado para selecionar os ítens, a edição acontecerá automaticamente. O ideal seria você definir uma tecla de atalho para permitir a alteração do ítem também via teclado. O Windows utiliza a tecla F2 para iniciar o modo de edição dos nomes de arquivos e pastas no Explorer. Talvez fosse uma boa manter este padrão, da mesma forma que o colega 2k sugeriu quanto ao clique sobre o ítem.
Abraços!
A diretiva de compilação {$J} serve para ativar/desativar o uso de constantes tipadas. A partir do Delphi 6 não é mais possível alterar o valor de uma constante por padrão, apenas utilizar seu conteúdo. Com essas diretivas você ativa esta utilização. Eu utilizei uma constante para manter a variável dentro do procedimento Click da TreeView. Você poderia entretanto criar uma variável global, ou definir um campo do objeto do formulário principal e fazer o mesmo. Para mais informações sobre constantes consulte [url]http://www.clubedelphi.com.br/artigos/Consttip.html[/url]. Se você não colocar essas diretivas no código em questão, o Delphi irá gerar um erro dizendo que você não pode atribuir um valor a uma constante.
Analisando o seu problema, eu percebi duas coisas que devem ser levadas em consideração. Vamos a elas:
1. Utilizar a propriedade Level para definir quais itens são editáveis pode não ser uma maneira prática de localizar tais itens, pois se você futuramente colocá-los um nível abaixo, ou acima, você terá que retornar ao código e alterar o valor de ´Level´ para a nova posição do item. Para contornar isso, você pode fazer o seguinte: O objeto TTreeNode não tem a propriedade Tag, que serviria como uma luva aqui. Porém, existem outras como StateIndex, SelectedIndex e OverlayIndex. A menos que você utilize-as todas em seu aplicativo, você poderia definir um valor de edição, como 1 por exemplo, para alguma delas e assim definir qual ítem é editável. Ficaria muito mais prático lidar com edições na TreeView desta forma,
...
{ Permite a edição apenas se o item selecionado estiver setado para isso}
TreeView1.ReadOnly := not (TreeView1.Selected.OverlayIndex = 1);
...
2. O último código que lhe passei permite apenas a edição automática do ítem quando o usuário clica sobre ele. Porém, se os usuários de seu programa utilizarem o teclado para selecionar os ítens, a edição acontecerá automaticamente. O ideal seria você definir uma tecla de atalho para permitir a alteração do ítem também via teclado. O Windows utiliza a tecla F2 para iniciar o modo de edição dos nomes de arquivos e pastas no Explorer. Talvez fosse uma boa manter este padrão, da mesma forma que o colega 2k sugeriu quanto ao clique sobre o ítem.
Abraços!
GOSTEI 0
Michael
18/06/2004
pois você poderia definar qualquer ítem para edição, em qualquer nível. Para se utilizar desta abordagem, basta alterar o código anterior para:
GOSTEI 0
Xanatos
18/06/2004
Tambem nao entendi! mas nao deixa de ser interessante!!! 8)
Mas... Se voce fizer dessa maneira tambem funciona!!! colocando o imageindex como tag!!! ou algo assim!
Mude a propriedade ChangeDelay=50 e tambem funciona!! é sempre bom termos alternativas!!!! :arrow:
Mas... Se voce fizer dessa maneira tambem funciona!!! colocando o imageindex como tag!!! ou algo assim!
if Node.ImageIndex =1 then begin TVmenu.Selected.EditText; end;
Mude a propriedade ChangeDelay=50 e tambem funciona!! é sempre bom termos alternativas!!!! :arrow:
GOSTEI 0
Michael
18/06/2004
(...) Porém, se os usuários de seu programa utilizarem o teclado para selecionar os ítens, a edição acontecerá automaticamente. (...)
O correto é que a edição [b:148678b6f3]não[/b:148678b6f3] será permitida. Esqueci do não... :oops:
GOSTEI 0
Vinicius2k
18/06/2004
Ao amigo Vinicius2k: meu nome é Michael, e não Michel!
:oops: perdõe-me... estamos empatados então... meu ´K´ é maiúsculo..
o usuário tem que abrir o node, clicar em cima dele 2 vezes, e ai sim ele abre para edição...
bem... este é o padrão do Windows... creio q para ficar livre dele, teria que usar o código do colega Michael mesmo...
[quote=´Lucas´]Qual é a função dos {$J+} e {$J-}
Código:
{$J+}
const UltimoItemEditado : TTreeNode = nil;
{$J-}
Notei que se não colocar dá um erro de código.[/code]
São diretivas de compilação que ´ligam (+)´ ou ´desligam (-)´ a possibilidade da procedure ou função escrever numa constante... (constantes tipadas)... para que se tenham comportamento semelhante à uma var... creio que o Micheal tenha usado este recurso para permitir a inicialização em conjunto com a declaração, já que uma var não permite isto dentro de procedures ou functions...
T+
GOSTEI 0
Lucas Silva
18/06/2004
Obrigado a todos que me ajudaram aqui.
Saiu exatamente do jeito que eu queria...
Michael, estou dando uma lida aqui neste artigo sobre Constantes Tipadas
Até mais pessoal.
Muito Obrigado!
:lol: :lol:
Saiu exatamente do jeito que eu queria...
Michael, estou dando uma lida aqui neste artigo sobre Constantes Tipadas
Até mais pessoal.
Muito Obrigado!
:lol: :lol:
GOSTEI 0
Michael
18/06/2004
Que coisa hein amigo Vinicius... Ambos erramos os nomes um do outro... ;-)
Na verdade eu usei uma constante tipada para reaproveitar o seu valor em todas as vezes que a procedure for executada. As constantes tipadas, como sabemos, mantêm seu valor durante toda a execução do programa, e por isso as utilizei.
Abraços!
creio que o Micheal tenha usado este recurso para permitir a inicialização em conjunto com a declaração, já que uma var não permite isto dentro de procedures ou functions...
Na verdade eu usei uma constante tipada para reaproveitar o seu valor em todas as vezes que a procedure for executada. As constantes tipadas, como sabemos, mantêm seu valor durante toda a execução do programa, e por isso as utilizei.
Abraços!
GOSTEI 0