none
TabControl .... RRS feed

  • Pergunta

  • Bom ocorre o seguinte erro quando vou alimentar um tabitem...

     

    Profundidade da árvore lógica excedida durante o desvio da árvore. Isso pode indicar um ciclo na árvore.

     

    gridEndereco2.Children.Add(mainEnde); //StackPanel

    gridEndereco2.Children.Add(mainContatos); //StackPanel   <--Erro ocorre aqui...

     

    tb.Content = gridEndereco2; //TabItem

     

    tabEnderecoContato.Items.Add(tb); //TabControl

     

     

    se alguem puder ajudar ficarei grato!

    terça-feira, 11 de novembro de 2008 13:26

Respostas

  • Seu código ficou faltando algumas coisas, mas se foi isso que você colocou, não deveria dar erro:

     

    Code Snippet

    Grid gridEndereco2 = new Grid();

    StackPanel mainEnde = new StackPanel();

    mainEnde.Children.Add(new TextBlock());

    mainEnde.Children.Add(new TextBox());

    StackPanel mainContatos = new StackPanel();

    mainContatos.Children.Add(new TextBlock());

    mainContatos.Children.Add(new TextBox());

    gridEndereco2.Children.Add(mainEnde); //StackPanel

    gridEndereco2.Children.Add(mainContatos); //StackPanel <--Erro ocorre aqui...

    TabItem tb = new TabItem();

    tb.Header = "Item";

    tb.Content = gridEndereco2; //TabItem

    tabEnderecoContato.Items.Add(tb); //TabControl

     

     

     

    Note que um TabItem só pode ter um filho. O erro que você mencionou parece com fazer algo semelhante a:

    tb.Content = tb

     

    Bruno

    terça-feira, 11 de novembro de 2008 14:18
  • Acredito que você esteja adicionando um componente no lugar errado. Veja este código, ele adiciona um TabControl dentro do outro e um StackPanel dentro do outro e não dá erro.

     

    Code Snippet

    Grid gridEndereco2 = new Grid();

    Content = gridEndereco2;

    TabControl tab1 = new TabControl();

    TabItem item1 = new TabItem();

    item1.Header = "Item1";

    StackPanel stack1 = new StackPanel();

    item1.Content = stack1;

    tab1.Items.Add(item1);

    stack1.Children.Add(new ComboBox());

    stack1.Children.Add(new TextBox());

    TabControl tab2 = new TabControl();

    TabItem item2 = new TabItem();

    item2.Header = "Item2";

    stack1.Children.Add(tab2);

    tab2.Items.Add(item2);

    StackPanel stack2 = new StackPanel();

    stack2.Children.Add(new TextBox());

    stack2.Children.Add(new TextBox());

    item2.Content = stack2;

    StackPanel stack3 = new StackPanel();

    stack3.Orientation = Orientation.Horizontal;

    TextBlock text = new TextBlock();

    text.Text = "Texto";

    text.Margin = new Thickness(5);

    stack3.Children.Add(text);

    text = new TextBlock();

    text.Text = "Texto no SP Horizontal";

    text.Margin = new Thickness(5);

    stack3.Children.Add(text);

    stack2.Children.Add(stack3);

    gridEndereco2.Children.Add(tab1); //StackPanel

     

     

    Bruno
    terça-feira, 11 de novembro de 2008 16:35
  • A solução é criar campos privados na janela que guardam os elementos que você criou. Da maneira que você faz, se acrescentar um novo elemento, tudo quebra. Então faça algo como:

     

    TextBox textEndereco;

     

    na função que cria os elementos, você faz:

     

    textEndereco = new TextBox();

    stackEnderecos.Children.Add(textEndereco);

     

    e aí você pode referenciar como

      textEndereco.Text = contacts.Observacoes;

     

    Bruno

     

    terça-feira, 11 de novembro de 2008 20:18
  • Em primeiro lugar, acho que o melhor é fazer um novo post com a pergunta, pois assim fica mais fácil para o pessoal encontrar a resposta se estiver procurando, o post está ficando grande e já não tem mais relação com a pergunta inicial.

     

    A sua resposta está em UserControls. Crie um UseControl para o contato e quando instanciar, coloque apenas o UserControl. Fica mais fácil e você separa a lógica do contato da lógica do cliente.

     

    Agora, fazendo uma virada no seu programa, será que um TabControl dentro de outro TabControl é a melhor solução? Lembre-se que a grande vantagem do WPF é a interface com usuário. Dê uma repensada em sua interface e veja se não há alternativas melhores, mesmo que a primeira vista pareçam malucas. Com WPF você pode se dar a esse luxo.

     

    Bruno

     

    quarta-feira, 12 de novembro de 2008 12:56

Todas as Respostas

  • Seu código ficou faltando algumas coisas, mas se foi isso que você colocou, não deveria dar erro:

     

    Code Snippet

    Grid gridEndereco2 = new Grid();

    StackPanel mainEnde = new StackPanel();

    mainEnde.Children.Add(new TextBlock());

    mainEnde.Children.Add(new TextBox());

    StackPanel mainContatos = new StackPanel();

    mainContatos.Children.Add(new TextBlock());

    mainContatos.Children.Add(new TextBox());

    gridEndereco2.Children.Add(mainEnde); //StackPanel

    gridEndereco2.Children.Add(mainContatos); //StackPanel <--Erro ocorre aqui...

    TabItem tb = new TabItem();

    tb.Header = "Item";

    tb.Content = gridEndereco2; //TabItem

    tabEnderecoContato.Items.Add(tb); //TabControl

     

     

     

    Note que um TabItem só pode ter um filho. O erro que você mencionou parece com fazer algo semelhante a:

    tb.Content = tb

     

    Bruno

    terça-feira, 11 de novembro de 2008 14:18
  • Então meu código está do mesmo jeito que você menciona....

     

    Só que o problema é que , são 2 TabControls 1 dentro de outro.

    E eles são criados em run-time a partir do evento de 1 botão.

     

    Então logo tive que criar desta forma....

     

    TabControl - TabItem - Grid ou StackPanel - Combobox,textbox,labels(Alinhamento Top) + TabControl (alinhamento Bottom) - TabItem - StackPanel(Main) - StackPanel (Linhas , orientacao Horizontal) - StackPanel (Colunas, orientacao Vertical) - Labels + TextBox + ComboBox.

     

    Fico em torno de 600 linhas em C# de codigo, e me equivoquei quando apontei o erro.

     

    gridEndereco2.Children.Add(mainEnde); //StackPanel

    gridEndereco2.Children.Add(mainContatos); //StackPanel  

     

    tb.Content = gridEndereco2; //TabItem <--Erro ocorre aqui...( Profundidade da árvore lógica excedida durante o desvio da árvore. Isso pode indicar um ciclo na árvore.)

     

    tabEnderecoContato.Items.Add(tb); //TabControl

     

    Essa parte de codigo é o final onde ele cria todos os objetos e vai juntando até poder ter 1 só para alimentar o TabItem Principal.

    Obrigado

    terça-feira, 11 de novembro de 2008 15:37
  • Acredito que você esteja adicionando um componente no lugar errado. Veja este código, ele adiciona um TabControl dentro do outro e um StackPanel dentro do outro e não dá erro.

     

    Code Snippet

    Grid gridEndereco2 = new Grid();

    Content = gridEndereco2;

    TabControl tab1 = new TabControl();

    TabItem item1 = new TabItem();

    item1.Header = "Item1";

    StackPanel stack1 = new StackPanel();

    item1.Content = stack1;

    tab1.Items.Add(item1);

    stack1.Children.Add(new ComboBox());

    stack1.Children.Add(new TextBox());

    TabControl tab2 = new TabControl();

    TabItem item2 = new TabItem();

    item2.Header = "Item2";

    stack1.Children.Add(tab2);

    tab2.Items.Add(item2);

    StackPanel stack2 = new StackPanel();

    stack2.Children.Add(new TextBox());

    stack2.Children.Add(new TextBox());

    item2.Content = stack2;

    StackPanel stack3 = new StackPanel();

    stack3.Orientation = Orientation.Horizontal;

    TextBlock text = new TextBlock();

    text.Text = "Texto";

    text.Margin = new Thickness(5);

    stack3.Children.Add(text);

    text = new TextBlock();

    text.Text = "Texto no SP Horizontal";

    text.Margin = new Thickness(5);

    stack3.Children.Add(text);

    stack2.Children.Add(stack3);

    gridEndereco2.Children.Add(tab1); //StackPanel

     

     

    Bruno
    terça-feira, 11 de novembro de 2008 16:35
  •  

    Vlw obrigado !

    Consegui resolver!

    terça-feira, 11 de novembro de 2008 17:02
  •  

    Bruno aproveitando sua atenção como você faria para salvar esses itens , por exemplo , chegar até o TextBox.Text ...

     

    Porque faço da seguinte forma:

     

     

    ((TextBox)((StackPanel)((StackPanel)((StackPanel)((TabItem)tabContatos.ItemsIdea).Content).Children[3]).Children[0]).Children[1]).Text = contatcs.Observacoes;

     

     

    Classe Linq / Campo da Tabela

    contatcs.Observacoes

     

     

    Porque sempre tenho que fazer isso e acho meio trabalhoso...

     

    se tive ruma solução , ficarei mto agradecido!

    terça-feira, 11 de novembro de 2008 17:15
  • A solução é criar campos privados na janela que guardam os elementos que você criou. Da maneira que você faz, se acrescentar um novo elemento, tudo quebra. Então faça algo como:

     

    TextBox textEndereco;

     

    na função que cria os elementos, você faz:

     

    textEndereco = new TextBox();

    stackEnderecos.Children.Add(textEndereco);

     

    e aí você pode referenciar como

      textEndereco.Text = contacts.Observacoes;

     

    Bruno

     

    terça-feira, 11 de novembro de 2008 20:18
  • Interessante.

     

    Mas no caso tentei , fazer mais ou menos isso , só que tenho que percorrer indices dos TabItems...

    Pois eu tenho o mesmo campo em varios TabItems...

     

    Se puder me ajudar com essa duvida , você irá concerteza me economizar muitos Casts e bastante digitação. rs...

     

    E aproveitando mais um pouco de seu tempo...

     

    Como faço pra acessar um objeto em Run-time?

     

    No meu caso...

     

    Tenho um tabcontrol, e dentro deste tenho outro tabcontrol...

    Para você entender melhor meu problema , explicar mais ou menos como funciona....

    Irei cadastrar endereços e dentro desses endereços posso ter varios contatos...

    Por exemplo:

    No mesmo escritorio posso ter varias pessoas com que eu possa falar a respeito de algum assunto...

     

    Então é 1 endereço e varios contatos...

     

    Por isso uso 1 TabControl dentro de outra....

    Esta TabControl interna cadastro os contatos...

     

    Bom então fica minha duvida...

     

    Como faço para que quando eu clicar no Botão (Adicionar Contato) ele veja que já existe um Tab Criada e insira mais 1 TabItem neste já axistente através do selecteditem ...

     

    Não sei se expliquei bem , mas qualquer coisa pode perguntar que tento ser mais claro...

     

    Obrigado

    quarta-feira, 12 de novembro de 2008 12:31
  • Em primeiro lugar, acho que o melhor é fazer um novo post com a pergunta, pois assim fica mais fácil para o pessoal encontrar a resposta se estiver procurando, o post está ficando grande e já não tem mais relação com a pergunta inicial.

     

    A sua resposta está em UserControls. Crie um UseControl para o contato e quando instanciar, coloque apenas o UserControl. Fica mais fácil e você separa a lógica do contato da lógica do cliente.

     

    Agora, fazendo uma virada no seu programa, será que um TabControl dentro de outro TabControl é a melhor solução? Lembre-se que a grande vantagem do WPF é a interface com usuário. Dê uma repensada em sua interface e veja se não há alternativas melhores, mesmo que a primeira vista pareçam malucas. Com WPF você pode se dar a esse luxo.

     

    Bruno

     

    quarta-feira, 12 de novembro de 2008 12:56
  •  

    Opa

     

    Vou criar então....

    quarta-feira, 12 de novembro de 2008 13:00