Apaixonado por tecnologia. Trabalho com tecnologia desde 2003.

Saiba mais sobre minha vida profissional aqui .

Fale comigo.
Siga-me no Twitter
Ultimos comentários
Calendário de Posts
<<  novembro 2017  >>
stqqssd
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

Siga o @DicaDoNerd no Twitter e acompanhe as novidades


       Hoje, por incrível que pareça, poucas pessoas utilizam Tipo Anonimo e expressões lambdas. bem como, não utilizam as vantagens do Linq, e não estou dizendo do LinqToSql, mas sim do Linq To Objects Linq To XML. Neste artigo vou mostra que podemos criar de forma muito simples (e performática) a criação de tipos anônimos e como recupera-los.

       Vamos supor que você queira passar uma estrutura para o um método com 3 parâmetros. Vamos fazer isso com um tipo anonimo.

Criação do objeto do Tipo Anonimo.

object InformacoesCliente = new 
{
Idade = 27,
NomeCliente = "Alexandre Minato",
Ativo = true,
Site = "www.alexandreminato.com.br"
};

Beleza, agora como recuperar? Por reflection. Óbviamente você poderia cria rum método para devolver o tipo, mas, vamos fazer isso de uma forma simples:

public void IncluirInformacoes(object Parametros)
{

string NomeCliente = (string)Parametros.GetType().GetProperty("NomeCliente").GetValue(Parametros, null);
int Idade = (int)Parametros.GetType().GetProperty("Idade").GetValue(Parametros,null);
bool Ativo = (bool)Parametros.GetType().GetProperty("Ativo").GetValue(Parametros,null);

}

 

Vamos ver o que aconteceu? Notem que só estou passandro um parâmetro do tipo object !

anonimo

Agora, vejam o tipo do parâmetro.

tip

Muito bom né?

Até a próxima

Minato. 8-)

     Neste artigo vou demonstrar uma forma muito simples de criar uma TreeView, funcional com manutenção simples e com um estilo legal. Para criar esta TreeView utilizei LinqToSql que facilita muito a vida de qualquer programador. O primeiro passo é criar duas tabelas: Uma delas irá conter as url’s com as imagens de cada nó e outra o cadastro do nó (TreeNode).

Diagrama do Banco de Dados
Banco  
Diagrama das Classes (DataContext)  
Datacontext  

Script para criação do Banco de dados

USE [dbTreeView]
GO
/****** Object: Table [dbo].[tbIcones] Script Date: 05/02/2010 01:17:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tbIcones](
[IDIcone] [int] IDENTITY(1,1) NOT NULL,
[Descricao] [varchar](20) NOT NULL,
[urlImagem] [varchar](50) NOT NULL,
CONSTRAINT [PK_tbIcones] PRIMARY KEY CLUSTERED
(
[IDIcone] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[tbTreeView] Script Date: 05/02/2010 01:17:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tbTreeView](
[IDNo] [int] IDENTITY(1,1) NOT NULL,
[Alias] [varchar](20) NOT NULL,
[ParentID] [int] NOT NULL,
[IDIcone] [int] NOT NULL,
CONSTRAINT [PK_tbTreeView] PRIMARY KEY CLUSTERED
(
[IDNo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: ForeignKey [FK_tbTreeView_tbIcones] Script Date: 05/02/2010 01:17:11 ******/
ALTER TABLE [dbo].[tbTreeView] WITH CHECK ADD CONSTRAINT [FK_tbTreeView_tbIcones] FOREIGN KEY([IDIcone])
REFERENCES [dbo].[tbIcones] ([IDIcone])
GO
ALTER TABLE [dbo].[tbTreeView] CHECK CONSTRAINT [FK_tbTreeView_tbIcones]
GO

Tudo gerado, mãos a obra.

     Para preencher os nós e seus respectivos filhos teremos que utilizar recursividade no preenchimento dos TreeNode’s, vamos criar um método que recebe um objeto TreeView e o ID do nó como parâmetro que começaremos a preencher.

     No contrutor da classe Preenchimento(), atribuo coloco em memória os dados que utilizaremos (lista de ícones e Lista de nós).

private dbTreeViewDataContext _db;
private List<IconeEntidade> _icones;
private List<TreeViewEntidade> _TreeView;
public Preenchimento()
{
//Carrego tudo na memória para fazer as iterações
_db = new dbTreeViewDataContext();
//Como não faremos nenhum Update,desabilito a segmentação
//para evitar que o linq faça o mapeamento do que está sendo alterado
//com isso ganhamos performance.
_db.ObjectTrackingEnabled = false;
//Coloco em memória a lista de icones.
_icones = _db.IconeEntidades.ToList<IconeEntidade>();
//Coloco em memória a lista que contem os nós que será preenchida
_TreeView = _db.TreeViewEntidades.ToList<TreeViewEntidade>();

}

Agora vamos preencher os TreeNode’s pai e para cada TreeNode, preenchemos seus filhos.

public void PreencherTreeView(System.Web.UI.WebControls.TreeView objTreeView, int IDNoCarregar)
{
//Limpo os nodes existentes.
objTreeView.Nodes.Clear();

//passo por todos os nodes que foi passado como parâmetro para carregar. (organizando em ordem alfabética
foreach (var item in _TreeView.Where(p => p.ParentID == IDNoCarregar).OrderBy(p => p.ParentID).OrderBy(p => p.Alias))
{
//Preencho o nó pai
TreeNode nodePai = new TreeNode();
nodePai.Value = item.IDNo.ToString();
nodePai.Text = item.Alias;
nodePai.ImageToolTip = item.Alias;
nodePai.ImageUrl = _db.IconeEntidades.Where(p => p.IDIcone == item.IDIcone).FirstOrDefault().urlImagem;
//Preecho os filhos
PreencherNoFilho(nodePai);

//Adiciono o nó que foi preenchido
objTreeView.Nodes.Add(nodePai);
}

}

Para preencher os TreeNode’s filhos, recebemos o TreeNode pai (parent).

protected void PreencherNoFilho(TreeNode parentNode)
{
//Passo por todos os elementos filhos do nó pai
foreach (var item in _TreeView.Where(p => p.ParentID == int.Parse(parentNode.Value)).OrderBy(p => p.ParentID).OrderBy(p => p.Alias))
{

TreeNode noFiltro = new TreeNode(item.Alias,item.IDNo.ToString(),
_icones.Where(p => p.IDIcone == item.IDIcone).FirstOrDefault().urlImagem); //Adiciono a url da imagem
noFiltro.ImageToolTip = item.Alias; // Atribuo o texto que será exibido
noFiltro.SelectAction = TreeNodeSelectAction.SelectExpand; //Expando no nó.
parentNode.ChildNodes.Add(noFiltro); //adiciono na coleção de nós
PreencherNoFilho(noFiltro); //Preenchemos os filhos deste Node (recursividade)
}
}

Nossa estrutura pronta, vamos partir para a formatação.

Continua - Parte II

     Neste artigo vou demonstrar uma forma muito simples de criar uma TreeView, funcional com manutenção simples e com um estilo legal. Para criar esta TreeView utilizei LinqToSql que facilita muito a vida de qualquer programador. O primeiro passo é criar duas tabelas: Uma delas irá conter as url’s com as imagens de cada nó e outra o cadastro do nó (TreeNode).

Diagrama do Banco de Dados
Banco  
Diagrama das Classes (DataContext)  
Datacontext  

Script para criação do Banco de dados

USE [dbTreeView]
GO
/****** Object: Table [dbo].[tbIcones] Script Date: 05/02/2010 01:17:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tbIcones](
[IDIcone] [int] IDENTITY(1,1) NOT NULL,
[Descricao] [varchar](20) NOT NULL,
[urlImagem] [varchar](50) NOT NULL,
CONSTRAINT [PK_tbIcones] PRIMARY KEY CLUSTERED
(
[IDIcone] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[tbTreeView] Script Date: 05/02/2010 01:17:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tbTreeView](
[IDNo] [int] IDENTITY(1,1) NOT NULL,
[Alias] [varchar](20) NOT NULL,
[ParentID] [int] NOT NULL,
[IDIcone] [int] NOT NULL,
CONSTRAINT [PK_tbTreeView] PRIMARY KEY CLUSTERED
(
[IDNo] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: ForeignKey [FK_tbTreeView_tbIcones] Script Date: 05/02/2010 01:17:11 ******/
ALTER TABLE [dbo].[tbTreeView] WITH CHECK ADD CONSTRAINT [FK_tbTreeView_tbIcones] FOREIGN KEY([IDIcone])
REFERENCES [dbo].[tbIcones] ([IDIcone])
GO
ALTER TABLE [dbo].[tbTreeView] CHECK CONSTRAINT [FK_tbTreeView_tbIcones]
GO

Tudo gerado, mãos a obra.

     Para preencher os nós e seus respectivos filhos teremos que utilizar recursividade no preenchimento dos TreeNode’s, vamos criar um método que recebe um objeto TreeView e o ID do nó como parâmetro que começaremos a preencher.

     No contrutor da classe Preenchimento(), atribuo coloco em memória os dados que utilizaremos (lista de ícones e Lista de nós).

private dbTreeViewDataContext _db;
private List<IconeEntidade> _icones;
private List<TreeViewEntidade> _TreeView;
public Preenchimento()
{
//Carrego tudo na memória para fazer as iterações
_db = new dbTreeViewDataContext();
//Como não faremos nenhum Update,desabilito a segmentação
//para evitar que o linq faça o mapeamento do que está sendo alterado
//com isso ganhamos performance.
_db.ObjectTrackingEnabled = false;
//Coloco em memória a lista de icones.
_icones = _db.IconeEntidades.ToList<IconeEntidade>();
//Coloco em memória a lista que contem os nós que será preenchida
_TreeView = _db.TreeViewEntidades.ToList<TreeViewEntidade>();

}

Agora vamos preencher os TreeNode’s pai e para cada TreeNode, preenchemos seus filhos.

public void PreencherTreeView(System.Web.UI.WebControls.TreeView objTreeView, int IDNoCarregar)
{
//Limpo os nodes existentes.
objTreeView.Nodes.Clear();

//passo por todos os nodes que foi passado como parâmetro para carregar. (organizando em ordem alfabética
foreach (var item in _TreeView.Where(p => p.ParentID == IDNoCarregar).OrderBy(p => p.ParentID).OrderBy(p => p.Alias))
{
//Preencho o nó pai
TreeNode nodePai = new TreeNode();
nodePai.Value = item.IDNo.ToString();
nodePai.Text = item.Alias;
nodePai.ImageToolTip = item.Alias;
nodePai.ImageUrl = _db.IconeEntidades.Where(p => p.IDIcone == item.IDIcone).FirstOrDefault().urlImagem;
//Preecho os filhos
PreencherNoFilho(nodePai);

//Adiciono o nó que foi preenchido
objTreeView.Nodes.Add(nodePai);
}

}

Para preencher os TreeNode’s filhos, recebemos o TreeNode pai (parent).

protected void PreencherNoFilho(TreeNode parentNode)
{
//Passo por todos os elementos filhos do nó pai
foreach (var item in _TreeView.Where(p => p.ParentID == int.Parse(parentNode.Value)).OrderBy(p => p.ParentID).OrderBy(p => p.Alias))
{

TreeNode noFiltro = new TreeNode(item.Alias,item.IDNo.ToString(),
_icones.Where(p => p.IDIcone == item.IDIcone).FirstOrDefault().urlImagem); //Adiciono a url da imagem
noFiltro.ImageToolTip = item.Alias; // Atribuo o texto que será exibido
noFiltro.SelectAction = TreeNodeSelectAction.SelectExpand; //Expando no nó.
parentNode.ChildNodes.Add(noFiltro); //adiciono na coleção de nós
PreencherNoFilho(noFiltro); //Preenchemos os filhos deste Node (recursividade)
}
}

Nossa estrutura pronta, vamos partir para a formatação.

Continua - Parte II

Continuando este artigo

     Vamos criar o arquivo de estilo da TreeView. (Estilo.css)

.TreeView{height:50px;color: #333333;position:absolute;clear: left;}
.TreeView p {border: 1px solid #999999;height: 15px;width: 250px;color: #666666;font-family: verdana;font-size: 9px;font-weight: bold;font-style: normal;background-color: #F7F7F7;padding: 5px 3px 3px 10px;}
.EstiloNo{font-family: Verdana; color: #333333; font-size: 10px; padding: 2px; margin-left: 2px;}
.EstiloNoCabecalho{ font-family: Verdana;color: #333333;font-size: 10px;padding: 2px;margin-left: 2px;font-weight: bold;}
.EstiloNoSelecionado{font-family: Verdana;color: #333333;font-size: 10px;padding: 2px;margin-left: 2px;font-style: italic;font-weight: bold;}


     Vamos criar o HTML, vejam que desabilitei o SessionState EnableSessionState”, claro que em um item como este não faz uma diferença significativa, mas, por boa prática, iremos desabilita-lo. Um dos grandes problemas com performance em projetos web é a habilitação de recursos que nunca são utilizados. (ViewState, SessionState e etc). Como a TreeView utiliza ViewState, deixei habilitado.

     Veja também, que ao utilizar o Ajax, habilitei no ScriptMananger a propriedade: EnablePartialRendering="true";

     No update panel, setei o modo de update para UpdateMode="Always"

     Por fim,  setei o objeto TreeView (AsyncPostBackTrigger) em uma Trigger dentro do UpdatePanel.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Minato.Exemplos.TreeView._Default" EnableSessionState="False" EnableViewState="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Exemplo treeView Recursiva - Alexandre Minato</title>
<link href="App_Themes/Estilo.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="frmPrincipal" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
<div class="TreeView">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
<ContentTemplate>
<p><asp:Label ID="lblMensagem" runat="server" Text="Selecione um nó" /></p>
<asp:TreeView ID="objTreeView" runat="server" onselectednodechanged="objTreeView_SelectedNodeChanged">
<RootNodeStyle CssClass="EstiloNoCabecalho" />
<SelectedNodeStyle CssClass="EstiloNoSelecionado" />
<LevelStyles>
<asp:TreeNodeStyle CssClass="EstiloNo" />
</LevelStyles>
<NodeStyle CssClass="EstiloNo" />
</asp:TreeView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="objTreeView" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
="true" />
<div class="TreeView">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
<ContentTemplate>
<p><asp:Label ID="lblMensagem" runat="server" Text="Selecione um nó" /></p>
<asp:TreeView ID="objTreeView" runat="server" onselectednodechanged="objTreeView_SelectedNodeChanged">
<RootNodeStyle CssClass="EstiloNoCabecalho" />
<SelectedNodeStyle CssClass="EstiloNoSelecionado" />
<LevelStyles>
<asp:TreeNodeStyle CssClass="EstiloNo" />
</LevelStyles>
<NodeStyle CssClass="EstiloNo" />
</asp:TreeView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="objTreeView" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>

     Vamos colocar a funcionalidade no CodeBehind e pronto!!! Tudo funcionando.

protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
PreencherTreeView();

}

protected void PreencherTreeView()
{
using (Preenchimento preenchimento = new Preenchimento())
{
preenchimento.PreencherTreeView(objTreeView, 0);

}

}

protected void objTreeView_SelectedNodeChanged(object sender, EventArgs e)
{
lblMensagem.Text = String.Format("Nó selecionado: {0}", objTreeView.SelectedNode.Text);

}

Agora vamos ver o resultado final desta implementação

tv 

 Demo onLine

Abraços

Minato 8-)

Baixem a Solução

Uma grande dificuldade que desenvolvedores em Acces tem é quando é necessário trabalhar com busca em todos os campos, para facilitar o trabalho eu utilizo um modelo padrão para as aplicações que desenvolvo (ultimamente não desenvolvo mais em VBA, Access, VB), mas confesso que sempre adorei e acho uma das ferramentas mais produtivas e que conto nos dedos as pessoas que conhecem de verdade esta ótima ferramenta.

A vantagem de utilizar esta solução é que basta você incluir um campo vinculado no formulário e o método se localização faz o resto :-)

A idéia é bem simples, vou concatenando a string da busca e montando um like de acordo com os controles que existe na tela. Segue o exemplo:

   1: Private Sub LocalizarTodosCampos()
   2:     'O código abaixo, localiza o critério em qualquer campo do formulário
   3:     'Cortesia de Alexandre Minato
   4:     'Permitida a distribuição / utilização desde que mantido os créditos
   5:     
   6:     If Me.txtFiltro = "<Informe o Filtro>" Then Exit Sub
   7:  
   8:     Dim sql As String
   9:     sql = "SELECT * FROM tblCadastro "
  10:  
  11:  
  12:     Dim contador As Byte
  13:     contador = 0
  14:  
  15:     If Not IsNull(Me.txtFiltro) Then
  16:         sql = sql + " WHERE "
  17:         Dim ctl As Control
  18:         For Each ctl In Me.Controls
  19:             
  20:             If ctl.ControlType = acTextBox Then
  21:                 If Len(ctl.ControlSource) > 0 And ctl.Locked = False Then
  22:                     If contador > 0 Then sql = sql + " OR "
  23:                         sql = sql + "(" + ctl.ControlSource + " Like '*' & '" + Me.txtFiltro + "' & '*') "
  24:                         contador = contador + 1
  25:                 End If
  26:             End If
  27:         Next
  28:     
  29:     End If
  30:  
  31: Me.Form.RecordSource = sql
  32: Me.Recalc
  33: End Sub

 

O resultado da pesquisa pode ser visto abaixo:

Sem título

Bom, podemos ver um Toolip personalizado também que encontrei  neste site.

 

Até a próxima

Minato 8-)

Baixe e Exemplo

 
teste