PROBLEMA AO SELECIONAR FILHOS NO TREEVIEW

ALVAROVB2009 28/08/2024 17:44:02
#503519
Alterado em 28/08/2024 17:47:01 Pessoal boa tarde, estou com um problema para selecionar os filhos do meu treeview APENAS quando adiciono nivel 2 em diante.
Em anexo esta uma planilha com o resultado do meu select.

Aqui segue o meu preenchimento da treeview, tem até o nivel 4, más deixei comentado, pois estava testando para ver aonde dava o problema
private void PreencheListaEntidade(string CnaeSelecionado = "")
{
TrvEntidade.Nodes.Clear();
DtEntidade = Entidade.MostraEntidade(CnaeSelecionado);
foreach (DataRow registro in DtEntidade.Rows)
{
string TextoPai = registro["razaosocial"].ToString();
string NomePai = registro["codentidade"].ToString();
TreeNode TPai = new TreeNode(TextoPai)
{
Name = NomePai,
Text = TextoPai,
Tag = registro["codentidade"].ToString()
};

string NomeFilho = NomePai + registro["codlancmunicipio"].ToString();
string TextoFilho = registro["municipio"].ToString();
TreeNode TFilho = new TreeNode(TextoFilho)
{
Name = NomeFilho,
Text = TextoFilho,
Tag = registro["codlancmunicipio"].ToString()
};

string NomeCnae = NomeFilho + registro["codcnaelancamento"].ToString();
string TextoCnae = registro["cnae"].ToString() + " - " + registro["descricao"].ToString();
TreeNode TCnae = new TreeNode(TextoCnae)
{
Name = NomeCnae,
Text = TextoCnae,
Tag = registro["codcnaelancamento"].ToString()
};

//// string NomeSubCnae = NomePai + registro["CodLancamentoCneSubGrupo"].ToString();
// string NomeSubCnae = registro["CodLancamentoCneSubGrupo"].ToString();
// string TextoSubCnae = registro["CodCnaeSubGrupo"].ToString() + " - " + registro["DescricaoSubGrupo"].ToString();
// TreeNode TSubCnae = new TreeNode(TextoSubCnae)
// {
// Name = NomeSubCnae,
// Text = TextoSubCnae
// };

TreeNode[] NoPai = TrvEntidade.Nodes.Find(NomePai, true);
if (NoPai.Length == 0) TrvEntidade.Nodes.Add(TPai);

TreeNode[] NoFilho = TrvEntidade.Nodes.Find(NomePai, true);
if (NoFilho.Length != 0 && TrvEntidade.Nodes.Find(NomeFilho, true).Length == 0) NoFilho[0].Nodes.Add(TFilho);

TreeNode[] NoCnae = TrvEntidade.Nodes.Find(NomeFilho, true);
if (NoCnae.Length != 0 && TrvEntidade.Nodes.Find(NomeCnae, true).Length == 0) NoCnae[0].Nodes.Add(TCnae);

//TreeNode[] NoSubCnae = TrvEntidade.Nodes.Find(NomeCnae, true);
//if (NoSubCnae.Length != 0 && TrvEntidade.Nodes.Find(NomeSubCnae, true).Length == 0 ) NoSubCnae[0].Nodes.Add(TSubCnae);
}
}

Aqui é a rotina para marcar / desmarcar
private void TrvEntidade_AfterCheck(object sender, TreeViewEventArgs e)
{
if (Flag == false)
{
Flag = true;
MarcarFilhos(e.Node);
MarcarPais(e.Node);
Flag = false;
}
else
{
Flag = false;
}
}

private void MarcarFilhos(TreeNode NoSelecionado)
{
foreach (TreeNode item in NoSelecionado.Nodes)
{
//marcando ou desmarcando os filhos de acordo com o pai
item.Checked = NoSelecionado.Checked;// true;
MarcarFilhos(item);
}
}
private void MarcarPais(TreeNode NoSelecionado)
{
if (NoSelecionado.Parent != null)
{
if (NoSelecionado.Checked)
{
NoSelecionado.Parent.Checked = true; Aqui é onde fica parado com o erro - System.StackOverflowException
MarcarPais(NoSelecionado.Parent);
}
else
{
Boolean Continua = true;
foreach (TreeNode Irmao in NoSelecionado.Nodes)
{
if (Irmao.Checked == true)
{
Continua = false;
return;
}
}
if (Continua == true)
{
//verificar se tem filho ainda selecionado, para não tirar a seleção do pai
ExisteFilhoSelecionado = false;
foreach (TreeNode NoPai in NoSelecionado.Parent.Nodes)
{
if (NoPai.Checked == true) ExisteFilhoSelecionado = true;
}

if (ExisteFilhoSelecionado == false) NoSelecionado.Parent.Checked = false;
MarcarPais(NoSelecionado.Parent);
}
}
}
}

As tags dentro dos nós, eu criei na tentativa dele não se perder, más não deu certo, continuou com o mesmo problema

Agradeço desde já a ajuda de todos
ALVAROVB2009 30/08/2024 08:32:11
#503521
Alguém ja passou por isso? Não sei se estou montando os níveis corretos, estou montando um vínculo no name, e também no caso esse name não se repete
KERPLUNK 30/08/2024 09:27:31
#503522
Resposta escolhida
Vamos devagar, se entendi o que você quer fazer, é selecionar o pai, quando selecionar o filho, é isso? Esqueça código, explique a funcionalidade apenas. Tente dar detalhes, quanto mais melhor
KERPLUNK 30/08/2024 09:35:07
#503523
Se for isso, eu faria algo recursivo, assim:

private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
treeView1.AfterCheck -= treeView1_AfterCheck;

CheckAllChildNodes(e.Node, e.Node.Checked);

UpdateParentNodes(e.Node);

treeView1.AfterCheck += treeView1_AfterCheck;
}

private void CheckAllChildNodes(TreeNode node, bool isChecked)
{
foreach (TreeNode childNode in node.Nodes)
{
childNode.Checked = isChecked;

CheckAllChildNodes(childNode, isChecked);
}
}

private void UpdateParentNodes(TreeNode node)
{
if (node.Parent != null)
{
bool allChecked = true;
bool noneChecked = true;

foreach (TreeNode sibling in node.Parent.Nodes)
{
if (!sibling.Checked)
{
allChecked = false;
}
if (sibling.Checked)
{
noneChecked = false;
}
}

if (allChecked)
{
node.Parent.Checked = true;
}
else if (noneChecked)
{
node.Parent.Checked = false;
}
else
{
node.Parent.Checked = false;
}

UpdateParentNodes(node.Parent);
}
}


O que isso vai fazer:
- Selecionar o pai quando qualquer dos filhos for selecionado
- Selecionar todos os filhos quando o pai é selecionado
ALVAROVB2009 30/08/2024 10:10:35
#503524
Kerplunk obrigado pelo retorno

Então é isso mesmo que vc falou, ai selecionar o filho vai selecionar o pai e quando selecionar o pai vai selecionar os filhos.

O motivo que coloquei os códigos é que já tenho a parte recursiva, e que o problema só acontece quando eu incluo o nivel 2 em diante, ou seja,
pai - filho - filho do filho ( é que a da o problema ).
Então pode ser algo de errado que eu esteja fazendo no preenchimento da treeview ou na parte recursiva

Se no caso eu deixe apenas pai e filho, funciona perfeitamente, porém se eu for colocando filho dentro de filho é que da o erro que deixei anotado no código

ALVAROVB2009 30/08/2024 10:40:31
#503525
Kerplunk agradeço a sua ajuda, peguei o seu código e vou dar uma ajustada, pois em determinados momentos quando seleciona o filho, ele não esta selecionando o pai, más o seu código ja esta funcionando, mesmo eu colocando o terceiro nível, que no meu esquema não funcionava

Tópico encerrado , respostas não são mais permitidas