DATA GRID VIEW - AUTO RELACIONAMENTO
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.
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
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.
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
Se eu fosse você, eu desenharia tudo via GDI+ e faria meu próprio Grid do zero, herdado de um UserControl mesmo.
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
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.
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....
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.
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.