DATA GRID VIEW - AUTO RELACIONAMENTO

MICHAELL 28/07/2016 22:33:29
#465238
Olá galera...

tenho uma entidade com auto relacionamento da seguinte forma.
  public class Grupo { 

public int GrupoID { get ; set ; }
public int ? GrupoPaiID { get ; set ; }
public string Nome { get ; set ; }
public string Descricao { get ; set ; }

pública virtual Grupo GrupoPai { obter ; set ; }
pública virtual ICollection < Grupo > Grupos { obter ; set ; }
}

Property(g => g.GrupoPaiID).IsOptional(); // NAO OBRIGATORIO TER GRUPO PAI

HasOptional(p => p.GrupoPai) // UM GRUPO PODE TER UM GRUPOPAI
.WithMany(p => p.Grupos) // 1 GRUPOPAI PERTENCE A GRUPO
.HasForeignKey(p => p.GrupoPaiID); // CHAVE ESTRANGEIRA DE GRUPOPAI


a principio esta tudo certo..
estou conseguindo cadastrar grupos.. assim como subgrupos.

porém, não tenho nem ideia de como exibir esses grupos e subgrupos alinhados em um dataGridView.

gostaria de exibir algo como:

id | nome do grupo
01 | grupo de clientes
02 | .... Convenções
03 | ........ Convenção x
04 | ........ Convenção e
05 | .... Tipo
06 | ........ Consumidor final
07 | ........ Revenda
08 | ........ comércio


quem puder ajudar ou dar uma luz agradeço.
KERPLUNK 28/07/2016 22:50:20
#465239
Pense bem. Um grid, serve para exibir dados em um mesmo nível, ítens de uma lista e coisas assim. O que você quer são dados que estão aninhados, então para exibir esses dados, o datagridview não é a melhor opção, mas sim um Nested DataGridView
MICHAELL 28/07/2016 23:04:59
#465240
nossa, achei muita gambiarra.. é não?!

poderia ser algo mais simples.. utilizando apenas o data grid view mesmo..
só não sei como fazer pra colocar na ordem.. e separar os niveis
KERPLUNK 28/07/2016 23:38:31
#465242
Citação:

:
nossa, achei muita gambiarra.. é não?!

poderia ser algo mais simples.. utilizando apenas o data grid view mesmo..
só não sei como fazer pra colocar na ordem.. e separar os niveis


Acho que você não entendeu. Cada célula em cada linha de um grid, é a representação de uma propriedade de uma classe de uma lista que são os dados. Um grid serve para exibir dados de uniformes, onde todos os ítens tem a mesma estrutura e podem ser representados por colunas. Repito: O que você quer exibir não é um grid, mas algum tipo de controle que suporte aninhamento, como um TreeView por exemplo. O artigo que passei, mostra um grid onde cada ítem pode ter múltiplos [Ô]filhos[Ô], como por exemplo, uma lista de receitas e cada receita mostra os ingredientes em um outro grid. Olhei o código do artigo, e não, não me parece gambiarra, é basicamente um grid que suporta outro grid como template de célula.
MICHAELL 05/08/2016 21:04:03
#465540
finalmente consegui.
custo, demorou.. mas saiu.




basicamente o que tive que fazer é criar uma coluna no banco chamado nível
a coluna nível recebe o valor do nivel do Grupo Pai + seu ID

ao salvar um Grupo, apenas deve verificar se tem Grupos Filhos, se tiver atualiza o Nível deles também

Ao carregar os dados no DataGridView... basta ordenar por Nível.
e para ter o espaço na visualização do grid, basta apenas multiplicar quantidade de Pontos que tem na coluna nível X quant. de espaços desejados... (pode ser espaço, pontos, traço)

Para carregar um ComboBox fica fácil também




Tentei utilizar o TreeView, mas ele não possuí colunas.
A consulta deveria ser diferente dos outros forms de Crud normal

Assim, até a consulta fica melhor
Posso pesquisar qualquer nível, sempre retorna o nível + os Filhos

Espero que ajude alguém também
Quem tiver sugestões.. agradeço

DS2T 06/08/2016 23:35:28
#465584
Cara, usar um DataGridView para esse fim é uma gambiarra monstro. Fora que não fica nada agradável aos olhos...

Se eu fosse você, eu desenharia tudo via GDI+ e faria meu próprio Grid do zero, herdado de um UserControl mesmo.
MICHAELL 07/08/2016 01:00:47
#465590

mas porque você acha que seria gambiarra? visto que fiz em poucas linhas de código...umas 10 linhas a mais apenas do que usei para criar um treeview


não vejo a necessidade de recriar um grid.. primeiro porque não sei criar ..
outra porque será utilizado apenas nessa tela.

quanto a visualização não achei desagradavel.. pois ficará padrão conforme a maioria das telas

DS2T 07/08/2016 10:42:38
#465594
O que define a gambiarra é usar um recurso para outro fim, além daquele para o qual foi criado. Tipo McGayver usando um chiclete para criar uma bomba atômica...
O datagridview foi criado para mostrar dados do mesmo nível, tanto é que não possui eventos relacionados aos filhos ou propriedades pra facilitar o retorno de childs, etc...

O que me incomodou muito na visualização, do jeito que você criou, é a primeira coluna (GrupoId). Talvez ficasse melhor, se você aplicasse os espaços nela também.
MICHAELL 07/08/2016 11:57:37
#465596
Citação:

:
Cara, usar um DataGridView para esse fim é uma gambiarra monstro. Fora que não fica nada agradável aos olhos...

Se eu fosse você, eu desenharia tudo via GDI+ e faria meu próprio Grid do zero, herdado de um UserControl mesmo.



cara, diante da sua [Ô]crítica[Ô] que pra mim foi bastante construtiva..
fiquei pensando em uma maneira de melhorar o código.. e consegui.

a gambiarra em si estava em ter que procurar no banco todos os nós filhos e alterar o nível.
qualquer problema ocorreria inconsistencia no bd.

acredito ter ficado melhor que utilizar o TreeView... pois utiliza menos código.. posso ter colunas e fica padrão a outras telas.

utilizando um TreeView por exemplo, teria que criar um método para criar os nodes.. exemplo:
   private void CriaNodes(List<Grupo> lista, TreeNode node)
{
int? parentID = node != null ? (int)node.Tag : 0;
if (parentID == 0)
parentID = null;

var nodesCollection = node != null ? node.Nodes : treeViewGrupos.Nodes;
foreach (var item in lista.Where(g => g.GrupoPaiID == parentID))
{
var newNode = nodesCollection.Add(item.GrupoID.ToString(), item.Nome);
newNode.Tag = item.GrupoID;
CriaNodes(lista, newNode);
}
}


já utilizando o GridView, só ter uma propriedade [Ô]Nivel[Ô] na Entidade.. sem gravar no BD
e utiliza o Método abaixo para criar os Níveis (mais ou menos semelhante ao TreeView)

  private void AtualizaFilhos(List<Grupo> lista, string nivel, int? id)
{
List<Grupo> listaFilhos = lista.Where(g => g.GrupoPaiID == id).ToList();
if (listaFilhos != null)
{
foreach (Grupo item in listaFilhos)
{
item.Nivel = nivel == [Ô][Ô] ? [Ô][Ô] : nivel + [Ô].[Ô];
item.Nivel += item.GrupoID;
AtualizaFilhos(lista, item.Nivel, item.GrupoID);
}
}
}


e só criei um metodo static de uma linha para retornar o espaço inicial ao carregar no grid
  public static string RetornaEspacoNivel(this string text) => new string([ô] [ô], Regex.Matches(text + [Ô][Ô], @[Ô]\.[Ô]).Count * 7); // 7 ESPAÇOS INICIAIS


valew pela dica....
KERPLUNK 08/08/2016 14:55:28
#465627
Citação:

:

mas porque você acha que seria gambiarra? visto que fiz em poucas linhas de código...umas 10 linhas a mais apenas do que usei para criar um treeview


não vejo a necessidade de recriar um grid.. primeiro porque não sei criar ..
outra porque será utilizado apenas nessa tela.

quanto a visualização não achei desagradavel.. pois ficará padrão conforme a maioria das telas


Só aqui você está cometendo dois erros fundamentais:
- [Ô]Não vejo necessidade de recriar um grid, primeiro porque não sei criar, outra porque será utilizado apenas nessa tela[Ô]
1 - Se você não sabe criar, você não tem como ver os benefícios que um componente personalizado vai trazer.
2 - Um dos maiores diferenciais de um bom programador é justamente [Ô]ver o futuro[Ô]. Não que você tenha que ser um [Ô]Nostradamus[Ô] e ver o fim do mundo, mas ver que um componente personalizado pode ser usado para projetos futuros e mesmo em outro lugar do mesmo projeto.

Não saber como criar um componente personalizado, não deve ser considerado uma barreira. Aprender como fazer isso não só enriquece seu conhecimento para quando surgir uma necessidade similar. Então se não sabe, aprenda, não fique preso no [Ô]não sei[Ô]. Existem milhares de tutoriais, vídeos, artigos e tudo mais com esse assunto. O problema é que a maioria requer um conhecimento prévio: Conhecimento de OOP. Venho batendo nessa tecla a anos. Aprendam OOP, aprendam OOP. Se você não aprendeu ainda, mesmo já tendo vídeos, tutoriais, artigos e tudo mais, tente de novo, procure mais informação, ache algum em que você aprenda isso. Não desista. Esse conhecimento é fundamental. Tanto que na minha opinião, quem não sabe isso(que é básico), não deveria seguir adiante com qualquer outro conhecimento em programação. Vou mais além: sem saber OOP, você não deveria sequer ter direito de instalar o Visual Studio e fazer o que uma grande parcela por aí fazem que é simplesmente ficar copiando e colando código. Então, só pra reforçar: aprenda OOP, depois aprenda como usar OOP e ABSOLUTAMENTE NADA MAIS SERÁ PROBLEMA. Mas só é possível entender o quão libertador OOP é, quando realmente se sabe. Então, correndo o risco de ser redundante: Aprenda OOP.
MICHAELL 08/08/2016 16:40:01
#465629
não saber.. foi apenas um modo de falar... apenas quis dizer que nunca criei (por isso ainda não saberia).. mas conseguiria criar de boa, sem problemas
como você mesmo falou, tem muito material na internet.

Só não estava querendo criar um novo componente para cada problema que encontrar.
Como falei, encontrei uma solução para o problema com menos linhas de código do que realmente seria necessário caso optasse por utilizar o TreeView.
Nesse caso, seria mesmo ideal criar um novo componente?

Acredito que o ideal para recriar um novo componente seja para poupar código e reutilizar em outros forms ou projetos ai sim, seria vantajoso.

Quanto ao OOP, com certeza não sou nenhum Experiente no assunto.. mas já aprendi muito em pouco tempo de estudo.

Quanto ao não ter o direito de instalar o Visual Studio por não saber utilizar o OOP, eu discordo.
Alguns podem aprender simplesmente lendo, outros apenas na prática.




Página 1 de 2 [12 registro(s)]
Tópico encerrado , respostas não são mais permitidas