Carlos Mattos

PPT da Palestra "Conheça a Melhor Linguagem de Programação de 2012" - FATEC Sorocaba

Para os alunos da FATEC Sorocaba que participaram da palestra "Conheça a Melhor Linguagem de Programação de 2012!", durante a Semana de Iniciação Científica e Tecnológica, aqui está o PPT utilizado na palestra: http://tinyurl.com/bnrt2ul.

Conheça a Melhor Linguagem de Programação de 2012 (C#)

Não percam nesta quinta-feira, dia 18/04/2013, às 19h00min, minha palestra "Conheça a Melhor Linguagem de Programação de 2012 - C#" que apresentarei durante a Semana de Iniciação Científica realizada pela FATEC Sorocaba. Para saber mais sobre este evento que tem início amanhã, confira a programação completa do evento no arquivo PDF anexo a este post.

SoroCódigo TechDay - ETEC Fernando Prestes - 11/05/2013

Oportunidade na GFT Brasil! Software Engineer .NET

Se você é um desenvolvedor .NET experiente, e está buscando uma oportunidade para trabalhar numa empresa global, que possa oferecer plano de carreira, programa de mentoring, diversos benefícios e ainda um excelente ambiente de trabalho, que proporcionará grandes oportunidades de desenvolvimento profissional, você deve é o profissional que procuramos! Anexo (e abaixo) está o descritivo completo desta oportunidade! Contate-nos, divulgue para seus contatos, redes sociais e universidades onde tem acesso! 

Job Description

This software engineer opening is on a team whose technologies include C#, Windows Client Applications, Web, Mobile, ASP.NET MVC, WCF and Entity Framework. As a software engineer on this team, you’d have responsibility for driving that from architecture and design through to execution and deployment. You’d also be working with a range of other engineering leaders giving you great opportunities for learning and growth.

As a software developer in you are expected to be a first class software engineer who prides yourself on delivering great quality code on schedule and in a collaborative environment working with other team members and customers.

Our team has a large range of projects, so great collaborative skills are a must. More than anything else, you have to believe fundamentally in delivering the best software solution for our customers.

 

Job Requirements

BS in Computer Science or equivalent experience required. MCSD, MCPD or other applicable advanced certification is strongly preferred, but not required at hire. Related field (or equivalent) experience will be considered. Candidates must possess current passport or be able to obtain passport within 45 days of hire.

 

Company Description

GFT provides information technology solutions in Europe. It engages in the consultation, systems integration, and the development and operation of applications, as well as in the procurement of information technology experts and outsourcing of information technology purchasing processes. The company operates in Germany, UK, France, Switzerland, Spain, Brazil, and the United States. GFT was founded by Ulrich Dietz in 1987.

 

Employee Benefits

·         Life Insurance

·         Health and Dental Care Insurance

·         Meal Allowances

·         Transportation Vouchers

·         Career and Mentoring Plan

·         Free English Classes

·         Complementary Pension Fund (after 1st year)

 

Additional Information

·         Type: Full-time (CLT)

·         Experience: Mid-Senior level

·         Functions: Software Development

·         Industries: Information Technology and Services

 

Apply for this job on Company’s website or send your resume to careerBrasil@gft.com.

Posted: Fri, Apr 5 2013 15:50 by Carlos Mattos | with no comments
Filed under:
DevBrasil Summit 2013 - Entity Framework

Para quem solicitou, aqui está o PPT usado durante minha apresentação no DevBrasil Summit 2013, realizado hoje na FIAP-SP.

 

Tem duvidas sobre sua carreira como desenvolvedor de software?

Code First Reverse Engineering apresenta erro com VS2012 Update 1

Se você está utilizando o Visual Studio 2012 e o Entity Framework Power Tools, após instalar o Update 1 do Visual Studio 2012, o mecanismo Code First Reverse Engineering apresenta um erro quando tentamos executá-lo. Este é um bug conhecido (veja aqui: http://tinyurl.com/ajvag6f). Para contornar este problema, até termos uma solução definitiva, o desenvolvedor deve editar os arquivos  EF.Utility.CS.ttinclude e EF.Utility.VB.ttinclude, localizados na pasta C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes\.

Basta remover a primeira linha, cujo conteúdo está apresentado abaixo:

<#@ CleanupBehavior Processor="T4VSHost" CleanupAfterProcessingTemplate="true" #> 

Salve os arquivos e o problema está resolvido. Você já pode executar novamente o Code First Reverse Engineering.

MVC + Telerik Kendo.UI na prática (Dica 1) - MVC4 Project References

Telerik Kendo.UI, para aqueles que ainda não tiveram contato, é uma nova suite de componentes Telerik baseados em HTML5 e JQuery. Esta série de posts explora o uso do Kendo.UI para construção de aplicações ASP.NET MVC com uma experiência visual rica para o usuário.

Para facilitar a criação de projetos baseados em seus controles, a Telerik oferece um assistente chamado Project Configuration Wizard que é exibido pelo Visual Studio quando você utiliza um dos templates de projetos da Telerik. Este assistente também pode ser iniciado a partir do menu Telerik -> Kendo UI for ASP.NET MVC -> Create New Kendo UI Project, como mostra a Figura 1.

Uma vez iniciado este assistente, o desenvolvedor pode escolher entre as vesões ASP.NET MVC 3 e ASP.NET MVC 4 (Veja a Figura 2). Os componentes Telerik Kendo UI são compatíveis com ambas as versões do ASP.NET MVC.

Contudo, ao optar pela versão ASP.NET MVC 4, o desenvolvedor poderá deparar-se com alguns erros de referências aos assemblies DotNetOpenAuth.AspNet, WebGrease e Newtonsoft.Json. O Visual Studio exibe a mensagem de erro abaixo quando o assistente da Telerik é finalizado.

Os erros são provocados pelas referências associadas a este template de projeto. Tenho observado muitos desenvolvedores buscando ajuda na Web para determinar a causa e encontrar uma solução para estes erros. Muitos tentam remover estas referências manualmente, editando o arquivo Package.config e até mesmo o arquivo do projeto (*.csproj). Na maioria das vezes sem obter sucesso. A Figura 3 apresenta a janela Solution Explorer com destaque para a pasta References do projeto, mostrando as referencias quebradas (pontos de exclamação em amarelo) para os assemblies não encontrados.

A boa notícia é que podemos corrigir as referências do nosso projeto ASP.NET MVC 4 de uma forma muito simples, utilizando o Nuget Package Manager Console. Considerando que você está enfrentando este problema, posso assumir que mesmo utilizando o Visual Studio 2010 você já possui a extensão NuGet instalada em seu computador. Se você tiver dúvidas sobre esta extensão do Visual Studio, ou como instalá-la, visite este endereço: http://docs.nuget.org/docs/start-here/installing-nuget. A figura abaixo mostra como iniciar o Package Manager Console a partir do menu Tools -> Library Package Manager.

Com o Package Manager Console aberto, o desenvolvedor deve executar os seguintes comandos:

PM>Install-Package WebGrease

PM>Install-Package DotNetOpenAuth.AspNet

PM>Install-Package Newtonsoft.Json

Após executar os comandos acima, as referências do seu projeto serão corrigidas automaticamente. A figura abaixo mostra o Package Manager Console após a execução dos comandos acima.

 

Posted: Sun, Jan 27 2013 21:35 by Carlos Mattos | with no comments
Filed under: ,
Introdução ao ASP.NET MVC4 com C#, Entity Framework e Razor Engine

Elaborei este documento para os desenvolvedores que buscam uma introdução aos conceitos e ferramentas básicas de uma aplicação MVC.

Existem diversos modelos de arquitetura para implementarmos uma aplicação MVC. Basta uma rápida pesquisa na Internet para que o desenvolvedor encontre um grande número de diferentes “sabores” de arquitetura para aplicações ASP.NET MVC.

Este grande número de opções, frequentemente gera dúvidas para os desenvolvedores que estão buscando uma referência para escolher a arquitetura correta para seu projeto. A escolha correta é aquela que se encaixa ao cenário do seu projeto. Todos os modelos de arquitetura oferecem seus prós e contras. O desenvolvedor deve analisar seu projeto e optar pelo modelo que mais se aproxima das necessidades da sua empresa, do cliente, do time de desenvolvimento.

Para construir a aplicação que ilustra os conceitos deste documento, optei pelo modelo que combina o uso de repositórios, UnitOfWork e IoC, também conhecido como Model 2, uma variação do padrão MVC. Este modelo oferece uma implementação relativamente simples e com resultados eficientes. Neste documento explicarei como adotar este modelo para suas aplicações MVC

Visual Studio 2012 Image Library

No último dia 30/11, a Microsoft disponibilizou para download a biblioteca de imagens do Visual Studio 2012. São mais de 5.000 imagens, distribuidas em cinco categorias principais: Common Elements, Actions, Anotations, AppIcons and Objects. São imagens que aparecem no Visual Studio, Windows, Office e outras softwares Microsoft. Acesse esta URL para baixar a biblioteca: http://www.microsoft.com/en-us/download/details.aspx?id=35825.

Como localizar colunas pelo nome em tabelas do SQL Server

Um cenário comum no ambiente de desenvolvimento de software é a necessidade do desenvolvedor de localizar tabelas do banco de dados SQL Server que contenham uma determinada coluna. Um script T-SQL muito simples pode ser utilizado para esta finalidade. Considere que você está buscando todas as tabelas que possuem a coluna “CustomerID” no banco de dados AdventureWorks no SQL Server. Observe o código apresentado na Figura 1 

Figura 1: T-SQL Encontrar Coluna por Nome

O script acima retornará uma lista com os nomes de todas as tabelas do banco de dados AdventureWorks que contém uma coluna denominada “CustomerID”. Observe a Figura 2.

Figura 2: Resultado do processamento do script da Figura 1

Existem formas diferentes para solucionar o problema proposto neste cenário. O exemplo acima, ilustra uma forma simples e prática. Você pode encapsular esse scritp numa stored procedure ou função para facilitar sua utilização pela equipe, até mesmo modificar o script para acrescentar informações relevantes para sua pesquisa.

Para saber mais:

Aprofunde seus conhecimentos sobre este tema visitando a comunidade SQL Server.

 

 

Testes preliminares do EF 5.0 indicam melhoria de performance acima de 60%

A Microsoft informou, ontem, 14/02/2012, através do Blog do Time de Produto ADO.NET, que os primeiros testes de performance com o Entity Framework 5.0 apresentaram excelentes resultados. Melhorias relacionadas à performance estão entre os principais objetivos do Time de Produto para a nova versão EF 5.0 (ainda não disponível para o público).

Um dos testes realizados, apontam uma performance seis vezes melhor para executar repetidamente a mesma consulta LINQ. A aplicação de testes do Time de Produto apresentou uma peformance 67% melhor comparada com a versão anterior.

O EF 5.0 introduz o novo recurso Automatic Compilation of LINQ to Entities. Desde a primeira versão do EF, os desenvolvedores podiam compilar suas consultas implementadas com LINQ explicitamente invocando o método CompiledQuery.Compile, mas muitos desenvolvedores não tinham conhecimento deste recurso ou encontravam dificuldades para utilizá-lo. No EF 5.0, a Microsoft facilitou o trabalho do desenvolvedor. Agora toda consulta LINQ será traduzida e armazenada em cache automaticamente, ou seja, sem utilizar o CompiledQuery. Esta alteração somada à outra otimização que avalia os valores dos parâmetros das consultas, resultaram num profundo impacto na performance do Entity Framework.

O gráfico acima representa o tempo de execução de uma consulta para recuperar uma entidade a partir de sua chave primária. A mesma consulta foi executada utilizando ADO.NET, LINQ-to-SQL e diferentes metodologias do Entity Framework. No melhor resultado obtido, a consulta é executada repetidas vezes, utilizando um valor diferente para chave a cada execução. Observando o gráfico, o desenvolvedor notará que antes das melhorias de performance do EF 5.0, o tempo necessário para executar uma consulta LINQ-to-Entities pela segunda vez era necessário 23,14 vezes maior comparado a execução da mesma consulta utilizando ADO.NET clássico. Com o novo recurso de compilação automática das consultas LINQ-to-Entities somado à melhoria que analisa os valores dos parâmetros da consulta o EF 5.0 apresentou performance 600% melhor comparado ao EF 4.0.

O Time de Produto informou que os trabalhos para melhorar a performance do EF 5.0 ainda não foram concluídos, e a expectativa é de resultados ainda mais expressivos para a versão final. O blog informa também que o Time de Produto está trabalhando numa versão beta do EF 5.0 que será disponibilizada para a comunidade de desenvolvedores para que esses resultados possam ser verificados.

A versão final, provavelmente, será liberada juntamente com o VS11 e o .NET Framework 4.5 já que o EF 5.0 implementa muitas melhorias disponíveis apenas no .NET 4.5. A boa notícia, é que toda aplicação que utiliza o Entity Framework terá um ganho significativo de performance automaticamente ao migrar para o .NET Framework 4.5.Confira o post completo no Blog do Time de ADO.NET (Inglês) neste endereço: http://blogs.msdn.com/b/adonet/archive/2012/02/14/sneak-preview-entity-framework-5-0-performance-improvements.aspx .

 

WPF | Como implementar ListBoxItem com ContextMenu

Posted: Wed, May 11 2011 8:23 by Carlos Mattos | with no comments
Filed under: , , ,
WPF - Como Aplicar DropShadowEffect num ListBoxItem

Como todos sabem, o WPF oferece diversos recursos para aprimorarmos a interface das nossas aplicações. Todos os controles do tipo Lista podem ser customizados para exibir os dados desejados. Um efeito muito comum utilizado nestes controles é o DropShadowEffect que aplica uma “sombra” sobre o item selecionado na lista. A cor e a profundidade desta sombra são definidas através dos parâmetros Color e ShadowDepth respectivamente.

Construindo o exemplo

Para ilustrar esse recurso do WPF, vamos construir uma lista de amigos. Os itens da lista exibirão os nomes e imagens. O efeito DropShadowBitmapEffect será aplicado no evento MouseOver. Veja a aplicação de exemplo em tempo de execução.

Figura 1: ListBoxItem com DropShadowEffect aplicado

Para construir a interface apresentada na Figura 1, abra o Visual Studio, crie um novo projeto baseado no Template WPF Application. Na Janela MainWindow.xaml altere o código XAML de acordo com os quadros a seguir.

O primeiro passo é criarmos a seção <Grid.Resources>onde depositaremos o DataSource que será utilizado para alimentar o ListBox e o ListItemContainerStyle que contém as definições para aplicação do efeito visual nos itens da lista.

O primeiro grupo de código XAML que adicionaremos na seção Grid.Resources utiliza o XmlDataSource para criar uma lista de amigos contendo Nome e Imagem de cada item.

Figura 2: Código XAML para criar o XmlDataSource

O segundo grupo de código XAML na seção Grid.Resources cria o ControlTemplate para o ListBoxItem. Observe que o Template é definido dentro do Tag <Style>.  Este código define como os registros serão apresentados e utiliza um Trigger associado à propriedade IsMouseOver para aplicar o efeito DropShadowBitmapEffect. Confira o código na Figura 3.

 

Figura 3: Definindo o estilo para o controle ListBox

 Finalmente, vamos ao código necessário para implementar nosso controle ListBox. Observe que a propriedade ItemSource é alimentada através do StaticResource e a propriedade ItemContainerStyle estabelece o vínculo com o estilo RedDropShadowEffect definido na seção Grid.Resources. Confira o código na Figura 4.

Figura 4: O código do controle ListBox

O mesmo estilo pode ser melhorado acrescentando outro Trigger associado à propriedade IsSelected, definindo outra cor para o efeito visual. Este é apenas um exemplo dos recursos gráficos que estão disponíveis no WPF.

 

Aprofunde seus conhecimentos sobre este tema visitando a comunidade WPF.

 

Faça download deste arquivo no formato PDF e também do código-fonte deste exemplo.

Posted: Mon, May 9 2011 13:12 by Carlos Mattos | with no comments
Filed under: ,
SQL – Como excluir registros duplicados numa tabela sem chave primária.

Um cenário comum no dia-a-dia, quando lidamos com bancos de dados, é a necessidade de identificarmos e removermos registros duplicados numa tabela. A dificuldade aumenta quando não há chave-primária nesta tabela.

 

A seguir vou demonstrar três métodos que podem ser utilizados para esta finalidade.

 

Criando a Tabela de Exemplo

Para ilustrar os métodos que vou apresentar, precisamos criar uma tabela de exemplo. Abaixo está o código para criarmos esta tabela.

 

if exists (select * from sysobjects where name like '%Celebridades%')

      drop table Celebridades

go

 

create table Celebridades(

      PrimeiroNome nvarchar(25),

      Sobrenome nvarchar(25)

)

go

Quadro 1: Criando a tabela de exemplo

 

Uma vez definida a tabela, precisamos alimentá-la com os registros duplicados.

 

insert into Celebridades(PrimeiroNome,Sobrenome) values('Minka','Kelly')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Keeley','Hazell')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Stacy','Ferguson')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Minka','Kelly')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Keeley','Hazell')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Cheryl','Cole')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Jennifer','Garner')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Scarlett','Johanson')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Stacy','Ferguson')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Natalie','Portman')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Katheryn','Winnick')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Minka','Kelly')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Stacy','Ferguson')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Natalie','Portman')

insert into Celebridades(PrimeiroNome,Sobrenome) values('LeeLee','Sobieski')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Megan','Fox')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Minka','Kelly')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Natalie','Portman')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Arianny','Celeste')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Brittney','Palmer')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Natalie','Portman')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Keeley','Hazell')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Megan','Fox')

insert into Celebridades(PrimeiroNome,Sobrenome) values('Minka','Kelly')

Quadro 2: Alimentando a tabela de exemplo com registros duplicados

Você pode observar que em nossa tabela de exemplo alguns registros se repetem por duas, três e até quatro vezes. Agora vamos trabalhar na exclusão dos registros duplicados. Não podemos utilizar a declaração DELETE FROM para excluir os duplicados desta forma:

 

delete from Celebridades where PrimeiroNome = 'Minka' AND Sobrenome = 'Kelly'

 

Este comando excluiria todos os registros com o nome Minka Kelly, e este não é o resultado esperado. Acompanhe a seguir três alternativas diferentes para solucionar esta questão.

 

 

Método 1: Utilizando o SET ROWCOUNT

 

A sintaxe para a declaração SET ROWCOUNT é:

 

SET ROWCOUNT { numero | @var_numero }

 

SET ROWCOUNT limita o SQL Server a processar um número específico de registros. Desta forma, o processo é interrompido após atingir o número de registros informado no argumento. O valor padrão para ROWCOUNT é 0 (zero), o que não estabelece limite para o comando, retornando todos os registros que atendam a cláusula WHERE.

 

Depois de executar o comando ROWCOUNT para limitar os registros que serão retornados pelo SQL, você pode executar o mesmo comando informando 0 (zero) como parametro para desabilitar esta opção.

 

Vamos tomar como exemplo o nome 'Minka Kelly', 5 registros serão retornados.

 

select * from Celebridades where primeironome = 'Minka' and sobrenome = 'Kelly'

 

Neste caso, precisamos excluir 4 dos 5 registros repetidos. Para isto devemos utilizar o ROWCOUNT atribuindo valor 4 para o parametro requerido. Veja o comando a seguir:

 

set rowcount 4

 delete from Celebridades where PrimeiroNome = N'Minka' and Sobrenome = N'Kelly'

set rowcount 0

-- (4 row(s) affected)

 

Depois de executar o comando acima, utilizando a declaração SET ROWCOUNT, execute o comando select e observe o resultado. Os registros repetidos foram excluídos.

 

select PrimeiroNome, Sobrenome from Celebridades

 

Você também pode utilizar o comando SET ROWCOUNT para excluir todos os registros duplicados da tabela de exemplo. Para atingirmos este objetivo, é necessário implementar um CURSOR.

 

Atenção ao declarar o CURSOR para identificar os registros duplicados, você deve definir o parametro do ROWCOUNT igual ao total de registros duplicados - 1, para preservar o registro original que será mantido na base após a execução deste comando.

 

Preste atenção no comando SET ROWCOUNT incluído no corpo do CURSOR.

 

declare @RegistrosDuplicados int

declare @PrimeiroNome nvarchar(25)

declare @Sobrenome nvarchar(25)

 

declare cursorDuplicados cursor fast_forward for

select PrimeiroNome, Sobrenome, count(*) - 1

from Celebridades

group by PrimeiroNome, Sobrenome

having count(*) > 1

 

open cursorDuplicados

 

fetch next from cursorDuplicados into @PrimeiroNome, @Sobrenome, @RegistrosDuplicados

 

while @@fetch_status = 0

 

begin

      set rowcount @RegistrosDuplicados

      delete from Celebridades where PrimeiroNome = @PrimeiroNome and Sobrenome = @Sobrenome

      set rowcount 0

      fetch next from cursorDuplicados into @PrimeiroNome, @Sobrenome, @RegistrosDuplicados

end

 

close cursorDuplicados

deallocate cursorDuplicados

Quadro 3: Utilizando o ROWCOUNT  com CURSOR

 

Método 2: Utilizando TOP

 

Um segundo método que podemos usar para remover registros duplicados é a expressão TOP combinada com a declaração DELETE. Desde o SQL 2005, como uma evolução do T-SQL, a expressão TOP passou a aceitar uma variável onde antes, no SQL 2000, só era possível atribuir uma constante numérica. Com esta mudança, podemos utilizar a expressão TOP dentro de um CURSOR para excluir todos os registros duplicados de uma só vez.

 

Utilizando nossa tabela de exemplo, podemos construir um comando para excluir os registros duplicados com o nome 'Minka Kelly', como apresentado nas linhas a seguir.

 

delete top(4) from Celebridades

 where PrimeiroNome = 'Minka' and Sobrenome = 'Kelly'

 

Trabalhando na mesma linha de raciocínio, podemos construir um CURSOR utilizando a expressão TOP. Veja o código abaixo.

 

declare @RegistrosDuplicados int

declare @PrimeiroNome nvarchar(25)

declare @Sobrenome nvarchar(25)

 

declare cursorDuplicados cursor fast_forward for

select PrimeiroNome, Sobrenome, count(*) - 1

from Celebridades

group by PrimeiroNome, Sobrenome

having count(*) > 1

 

open cursorDuplicados

 

fetch next from cursorDuplicados into @PrimeiroNome, @Sobrenome, @RegistrosDuplicados

 

while @@fetch_status = 0

 

begin

      delete top(@RegistrosDuplicados) from Celebridades where PrimeiroNome = @PrimeiroNome and Sobrenome = @Sobrenome

      fetch next from cursorDuplicados into @PrimeiroNome, @Sobrenome, @RegistrosDuplicados

end

 

close cursorDuplicados

deallocate cursorDuplicados

Quadro 4: Construindo CURSOR com a expressão TOP

 

Considere utilizar o método 2, com a expressão TOP, ao invés de utilizar o ROWCOUNT. A declaração ROWCOUNT não afetará os comandos DELETE, INSERT e UPDATE nas próximas versões do SQL. Consulte o Books On Line para mais informações (http://msdn.microsoft.com/en-us/library/ms188774.aspx).

 

Método 3: Adicionar uma coluna IDENTITY

 

O terceiro método é adicionar uma coluna IDENTITY na nossa tabela de exemplo. Execute o comando a seguir

para adicionar a coluna IDENTITY.

 

alter table Celebridades add Codigo int identity(1,1)

 

Agora, com a coluna IDENTITY podemos utilizar o comando DELETE para excluir os registros duplicados. Veja o exemplo a seguir.

 

delete from Celebridades where Codigo in(24,17,12,4)

 

Com a coluna IDENTITY inserida na nossa tabela de exemplo, podemos utilizar o recurso CTE (Common Table Expression) para excluir os registros duplicados, ao invés de usarmos um CURSOR. As CTEs foram introduzidas como aprimoramento do T-SQL a partir da versão 2005. Desta forma, o código abaixo não funcionará se voce tentar executá-lo no SQL Server 2000.

 

with CTEDuplicados(PrimeiroNome, Sobrenome, Codigo)

as

(

select PrimeiroNome, Sobrenome, Min(Codigo) Codigo

from Celebridades

group by PrimeiroNome, Sobrenome

having count(*) > 1

)

delete from Celebridades

where Codigo in (

select Celebridades.Codigo

from Celebridades

inner join CTEDuplicados

on Celebridades.PrimeiroNome = CTEDuplicados.PrimeiroNome

and Celebridades.Sobrenome = CTEDuplicados.Sobrenome

and Celebridades.Codigo <> CTEDuplicados.Codigo

)

Quadro 5: Utilizando CTE para excluir os registros duplicados

 

Após excluir os registros duplicados utilizando a CTE, você pode remover a coluna IDENTITY da tabela de exemplo executando o comando a seguir:

 

alter table Celebridades drop column Codigo

 

Aprofunde seus conhecimentos sobre este tema visitando a comunidade SQL Server no DevBrasil.

 

Faça download deste arquivo no formato PDF e também do código T-SQL deste exemplo.

Posted: Sat, May 7 2011 20:53 by Carlos Mattos | with 2 comment(s)
Filed under:
WPF - Criando Janelas Transparentes

São inúmeros os benefícios agregados ao WPF para os desenvolvedores que já possuem background em WindowsForms. Tenho explorado algumas dicas práticas e fáceis de implementar que ilustram alguns desses benefícios.  Quantas vezes, você – desenvolvedor WindowsForms – tentou criar formulários com formas geométricas diferentes das convencionais? Não é necessário responder. As alternativas que tínhamos, exigiam o uso de APIs Win32 para conseguirmos os resultados desejados.

Com WPF você pode criar facilmente formulários (janelas no WPF) das mais diversas formas. Por exemplo, você pode pegar uma imagem criada por um designer e utilizá-la como background da sua janela, acrescentar controles e funcionalidades como quaquer janela convencional.  

Veja abaixo um exemplo de janela transparente que apresenta a logomarca, criada por um designer profissional, para um software de gestão de bares e restaurantes que desenvolvi. Esta imagem é usada como splashscreen da aplicação. A Figura 1 apresenta a janela de splash em tempo de execução. A janela está limitada ao círculo da logomarca, o fundo azul é da minha Área de Trabalho.

Figura 1: Exemplo de Janela Transparente

Como não sou designer, e não me atrevo a desenhar nada, escolhi uma imagem com fundo transparente para ilustrar este artigo. Esta imagem apresenta alguns dados (daqueles de jogos), com aspecto de estarem em movimento e o fundo transparente. A imagem está no formato PNG. O objetivo aqui é demonstrar como você pode criar uma janela transparente de forma muito simples e prática. A Figura 2 apresenta nossa a janela transparente deste exemplo, em tempo de execução. Observe que o fundo preto pertence a Área de Trabalho, a janela está limitada a imagem dos dados e ao botão Fechar (imagem com X e fundo vermelho). O mais interessante neste recurso, é que você pode clicar entre os dados (na área transparente) e interagir com qualquer elemento que estiver atrás da janela, ou seja, sua janela assume a forma da imagem criada. Veja a Figura 3 onde há um ícone na Área de Trabalho que está selecionado entre os dados.

 Figura 2: A Janela Transparente em tempo de exeução

Figura 3: Ícone na Área de Trabalho selecionado através da janela transparente

Construindo o exemplo

Este artigo faz parte de uma série direcionada ao desenvolvedores iniciantes. O exemplo criado é simples e fácil de construir. Neste exercício de reproduzir o exemplo ilustrativo deste artigo, você aprenderá como criar uma janela transparente, como movimentar uma janela sem bordas utilizando o método Window.DragMove(), como utilizar os eventos Window.Closing e Window.KeyUp para interagir com sua aplicação. Para os absolutamente iniciantes, não só no WPF mas também na linguagem C#, no evento Window.Closing está um exemplo de aplicação da estrutura condicional switch com a enumeração MessageBoxResult. O template WPF Application foi utilizado para construir este exemplo. Veja a Janela Solution Explorer exibida na Figura 4.

Figura 4: A Janela Solution Explorer

A Janela Transparente MainWindow.xaml

São duas, as propriedades que devem ser ajustadas para esta tarefa. A propriedade AllowsTransparency deve ter valor True, e a propriedade Background deve ser definida como System.Windows.Media.ImageBrush. Você pode realizar esta tarefa utilizando a janela Properties Window, como mostra a Figura 5.

Figura 5: A janela Properties Window

Observe que a propriedade Background pode ser definida como uma cor sólida, gradiente ou uma imagem. Quando o desenvolvedor seleciona a opção imagem, a IDE do Visual Studio ainda permite que ele defina o comportamento da imagem ajustando as propriedades Stretch e Tile. Você ainda pode escolher uma imagem já incluída no projeto ou adicionar uma nova imagem a partir de uma pasta do FileSystem. Esses são apenas alguns dos recursos disponíveis na IDE o Visual Studio 2010. A propriedade WindowStyle também deve ser definida como True. Outra forma de ajustar estas propriedades é através do código XAML, como está demonstrado na Figura 6 a seguir.

 

Figura 6: O código XAML da janela MainWindow

A Imagem Transparente

Observe que não coloquei a imagem transparente (dados.png) como background da Janela, apenas defini que o background seria do tipo Image. E utilizei dois controles Image, um para a imagem de fundo (dados.png) e outro para o botão Fechar (X com fundo vermelho). Não coloquei a imagem dos dados diretamente no background da Janela para permitir o uso do método DragMove() de forma mais eficiente, associado ao evento MouseDown do controle Image. Poderia ter usado o evento MouseDown do container Grid, mas afetaria a resposta do evento Click da imagem usada como botão Fechar.

Codificando

As imagens a seguir apresentam o código C# necessário para implementar este exemplo. Observe atentamente os métodos, eventos, propriedades e objetos utilizados neste exemplo, você poderá utilizá-los em diversas situações.

  Figura 7: A sessão de declarações gerais

Figura 8: O código do controle Image usado como botão Fechar

Figura 9: O código do evento Window.KeyUp

Figura 10: O código associado ao evento Window.Closing

Figura 11: O método DragMove() associado ao evento MouseDown da imagem de fundo

 

Com isto, finalizamos nosso exemplo. Agora é só executar o aplicativo e observar o comportamento da janela transparente. Aprofunde seus conhecimentos sobre este tema visitando a comunidade WPF.

Faça download deste arquivo no formato PDF e também do código-fonte deste exemplo.

 

Posted: Sun, Mar 20 2011 19:17 by Carlos Mattos | with 1 comment(s)
Filed under: ,
WPF - Botões com Imagens Alternadas para Ativado, Pressionado e Desativado

Um dos controles mais utilizados em todas as aplicações é o Botão (Button). E a cada novo projeto tentamos mudar sua aparência para melhorar a experiência visual do usuário e tornar nossa interface mais funcional. Uma prática muito comum é o uso de imagens nos botões, as imagens auxiliam o usuário a interpretar o comando associado ao botão. Nas aplicações WPF existem diferentes formas de implementar botões com imagens e comportamentos das mais diversas formas e variações. O propósito deste artigo é demonstrar como criar um botão com imagens que se alternam de acordo com o estado do botão (ativado, pressionado ou desativado). O exemplo que utilizei para ilustrar este artigo é simples e de fácil implementação. As imagens a seguir apresentam o botão em tempo de execução nos seus diferentes status.

Figura 1: O botão com imagem (ativado)

Figura 2: O botão com imagem (desativado)

 Figura 3: O botão com imagem (pressionado)

 

Construindo o exemplo

Utilizaremos dois projetos para ilustrar este exemplo. O primeiro projeto deve ser criado com o template WPF Application e será a aplicação de teste para o nosso botão com imagem. O segundo projeto deve ser criado com o template User Control Library, este projeto implementará nosso SampleImageButton. A Figura 4 mostra a janela Solution Explorer com a Solução de exemplo.

Figura 4: O projeto de exemplo

 

Criando o Botão de Exemplo

Adicione ao projeto User Control Library as imagens que você deseja usar no seu botão customizado. No meu caso eu coloquei três imagens de um cubo. O cubo cinza será exibido quando o botão estiver desabilitado, a imagem vermelha quando o botão estiver pressionado e o cubo amarelo quando o botão estiver em seu estado normal. O Quadro 1 apresenta o código XAML necessário para implementar a classe MyImageButton.

 

<!--As propriedades Width, Height, MaxHeight, MaxWidth, MinWidth podem ser usadas

para definir o tamanho padrão do controle. Assim quando o developer arrastar

o controle a partir da ToolBox, ele será criado com seu tamanho padrão-->

<Button x:Class="ExemploWPFImageButton.MyImageButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="120" Height="90" MaxHeight="90" MaxWidth="120" MinHeight="90" MinWidth="120">

<Button.Template>

    <!--O ControlTemplate define o tipo de controle que será construido-->

    <ControlTemplate TargetType="{x:Type Button}">

        <!--Dois containers StackPanel e Grid acomodarão as imagens e o texto do botão-->

        <StackPanel Background="#FF232222" Width="120" Height="90">

            <Grid Margin="0,10,0,0">

                <!--As imagens que indicam os estados Pressionado e Desativado ficarão ocultas-->

                <!--A propriedade Visibility="Hidden" se encarrega desta tarefa-->

                <Image Name="Normal" Source="Images/cubeYellow.png" Height="48" Width="48"/>

                <Image Name="Pressed" Source="Images/cubeRed.png" Visibility="Hidden" Height="48" Width="48"/>

                <Image Name="Disabled" Source="Images/cubeGray.png" Visibility="Hidden" Height="48" Width="48"/>

            </Grid>

            <TextBlock TextAlignment="Center" FontWeight="Bold" Margin="10"

                        Foreground="WhiteSmoke">Clique no Cubo</TextBlock>

        </StackPanel>

        <!--Aqui está o responsável pela troca de imagens de acordo com o estado do botão-->

        <!--Os Triggers podem ser usados para diversas aplicações, este é um bom exemplo-->

        <ControlTemplate.Triggers>

            <!--O primeiro Trigger avalia a propriedade IsPressed-->

            <Trigger Property="IsPressed" Value="True">

                <!--O elemento Setter através do atributo TargetName estabelece o vínculo com a imagem-->

                <!--e o atributo Property indica a Propriedade, Value atribui o valor desejado-->

                <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/>

                <Setter TargetName="Pressed" Property="Visibility" Value="Visible"/>

            </Trigger>

                <!--O mesmo conceito é aplicado para avaliar a propriedade IsEnabled-->

            <Trigger Property="IsEnabled" Value="False">

                <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/>

                <Setter TargetName="Disabled" Property="Visibility" Value="Visible"/>

            </Trigger>

        </ControlTemplate.Triggers>

    </ControlTemplate>

</Button.Template>

</Button>

Quadro 1: Código XAML do controle MyImageButton

 

O Quadro 2 apresenta o código do arquivo MyImageButton.cs.

 

using System.Windows.Controls;

 

namespace ExemploWPFImageButton

{

    /// <summary>

    /// Interaction logic for MyImageButton.xaml

    /// </summary>

    public partial class MyImageButton : Button

    {

        public MyImageButton()

        {

            InitializeComponent();

        }

    }

}

Quadro 2: Código do arquivo MyImageButton.cs

 

Por último, vamos adicionar o botão na Janela MainWindow do projeto de exemplo. Observe o código XAML no Quadro 3.

 

<Window x:Class="ExemploWPFImageButton.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="DevBrasil | WPF | Image Button" Height="319" Width="351"

        xmlns:my="clr-namespace:ExemploWPFImageButton"

        xmlns:my1="clr-namespace:ExemploWPFImageButton;assembly=SampleImageButton">

<Grid Language="pt-BR" Background="#FF141212">

        <Button Content="Ativar/Desativar" Height="30" HorizontalAlignment="Left" Margin="103,198,0,0" Name="button1" VerticalAlignment="Top" Width="120" Click="button1_Click" />

        <my1:MyImageButton Content="Button" Height="23" HorizontalAlignment="Left" Margin="103,82,0,0" Name="myImageButton1" VerticalAlignment="Top" Width="75" />

    </Grid>

</Window>

Quadro 3: A janela MainWindow

 

 

Agora é só executar seu projeto de exemplo e observar o comportamento do botão em seus três estados diferentes. Existem diversas técnicas para criar controles customizados, este é um exemplo prático para customizar seus botões. Você pode empregar esta técnica para criar uma biblioteca de botões padronizados para sua aplicação.

 

Aprofunde seus conhecimentos sobre este tema visitando a comunidade WPF.

Faça download deste arquivo no formato PDF e também do código-fonte deste exemplo.

 

 

 

Posted: Sat, Mar 19 2011 16:43 by Carlos Mattos | with no comments
Filed under: ,
Como invocar o método SelectAll() para todos os controles TextBox numa aplicação WPF

Numa aplicação WindowsForms ou WPF uma prática muito comum é a utilização do método SelectAll() dos controles TextBox para selecionar o conteúdo digitado sempre que o controle recebe o foco. Este recurso é familiar para os usuários deste tipo de aplicação e agiliza a entrada de dados.

Você pode invocar o método SelectAll() a qualquer momento para selecionar o texto digitado no controle TextBox. Mas, uma forma prática para implementar este recurso é utilizar o evento OnStartup do objeto Application. Através deste evento você pode modificar o comportamento dos controles TextBox de forma que todos passem a disparar o método SelectAll() automaticamente, sempre que receberem o foco.

Esta abordagem não se limita aos controles TextBox, você pode utilizar a mesma técnica para customizar qualquer evento de qualquer controle utilizado na sua aplicação.

Exemplo prático

Para este exemplo, vamos criar um novo projeto com o template WPF Application. Eu chamei meu projeto de ExemploWPFTextBoxSelectAll. Na janela principal, MainWindow.xaml, adicione cinco controles TextBox. Defina o valor da propriedade Text com conteúdo aleatório, apenas para ilustrar o comportamento dos controles após nossa implementação. Sua janela MainWindow deverá apresentar aspecto semelhante ao da Figura 1.

Figura 1: A Janela MainWindow

Modificando o arquivo App.xaml.cs

Para esta abordagem, precisamos modificar o arquivo App.xaml.cs, acrescentando o código apresentado no Quadro1. O primeiro procedimento, protected override void OnStartup(StartupEventArgs e) substitui o evento original Application.OnStartup, registrando o novo conteúdo para o evento TextBox.GotFocusEvent.

Quadro 1: O arquivo App.xaml.cs

 

Testando a aplicação

Agora é só executar a aplicação e utilizar a tecla TAB para navegar através dos controles TextBox e observar que o método SelectAll() é executado selecionando o conteúdo dos controles. Outro exemplo no qual você pode aplicar esta mesma técnica é modificar o evento KeyDown dos controles TextBox para permitir que seu usuário navegue através dos controles, utilizando a tecla ENTER ao invés do TAB.

 

Aprofunde seus conhecimentos sobre este tema visitando a comunidade WPF.

 

Faça download deste arquivo no formato PDF e também do código-fonte deste exemplo.

 

 

Posted: Sat, Mar 19 2011 16:11 by Carlos Mattos | with no comments
Filed under: ,
Como Abrir Objetos Encapsulados em Assemblies Externos no WPF

Outra dúvida comum entre os desenvolvedores que estão iniciando refere-se a como podemos encapsular e consumir objetos (Janelas, Páginas e Imagens) em assemblies externos. Esta prática é comum e muito útil para você organizar seu projeto.

Por exemplo, em todas as aplicações, por mais simples que sejam, utilizamos imagens (ícones) para construir nossa interface com o usuário. Muitas vezes, encontro projetos nos quais os desenvolvedores utilizaram um mesmo conjunto de imagens, mas de uma forma inadequada, ou seja, copiando uma pasta de imagens em todos os projetos que precisavam. Isso cria uma poluição de arquivos de imagens que poderiam ser compartilhados através de uma biblioteca encapsulada num assembly.

Outro cenário comum é a necessidade de modularizarmos nosso projeto. Além das bibliotecas de códigos (nossas classes) que com maior frequência encontramos corretamente encapsuladas em assemblies, os desenvolvedores têm dúvidas quando precisam encapsular objetos da interface como Janelas (Window) e Páginas (Page).

Essas dúvidas não se limitam aos desenvolvedores WPF, são comuns também entre os desenvolvedores que trabalham com Windows Forms, principalmente quando se faz necessário implementar o conceito Late Biding. Mas isto é assunto para outro artigo na seção Windows Forms.

 Neste artigo vou demonstrar como encapsular e consumir imagens, janelas e páginas em assemblies externos. Então preste atenção, e mãos-a-obra. A Figura 1 apresenta a interface do nosso exemplo. Este exercício consiste em criar uma Janela com um TabControl e alguns botões. Ao clicar nos três primeiros botões, o aplicativo deverá criar um novo TabItem e exibir a página correspondente ao botão clicado. Os objetos Page estão encapsulados num assembly externo que originalmente chamei de ObjetosExternos.dll. O método AbrirPagina que ilustra esta funcionalidade, também demonstra como verificar se a página desejada já está carregada no TabControl, neste caso, o aplicativo apenas seleciona o TabItem correspondente.

Figura 1: Carregando Páginas e Janelas Externas

O botão btnAbrirJanelaExterna carrega um objeto Window, chamado JanelaExemploImagem, também encapsulado no mesmo assembly externo. Esta janela apresenta um objeto Image e três botões. Ao clicar em cada botão, a imagem exibida no controle Image é alterada. As imagens utilizadas também estão armazenadas num assembly externo chamado BibliotecaImagens.dll. Veja a Figura 2.

Figura 2: Carregando Imagens Externas

Para a Solução deste exemplo, foram criados três projetos: BibliotecaImagens, ExemploAbrindoObjetosExternos e ObjetosExternos. A Figura 3 apresenta a janela Solution Explorer.

 

Figura 3: A janela Solution Explorer

Desvio de percurso

E apenas para não perder a oportunidade, o último botão da janela principal deste exemplo, ilustra como encerrar nossa aplicação de forma explícita. Para isto, o arquivo App.xaml deve apresentar o parâmetro ShutdownMode com o valor OnExplicitShutdown, como mostra a Figura 4.

Figura 4: Definindo o ShutdownMode no arquivo App.xaml

O código associado ao botão btnSairExemplo está apresentado no Quadro 1, logo abaixo:

private void btnSairExemplo_Click(object sender, RoutedEventArgs e)
{
   Application.Current.Shutdown();
}

Quadro 1: O método Shutdown()

Voltando aos Assemblies Externos

O método AbrirPagina() será o primeiro a ser explicado. Este método requer três parâmetros, apresentados abaixo:

 

Assembly

Nome do Assembly Externo que contém o objeto Page desejado. Neste exemplo o assembly que contém as páginas chama-se ObjetosExternos. Na prática, se você construir um assembly com Namespaces compostos, você deverá passar o Namespace completo neste parâmetro. Exemplo: DevBrasil.ObjetosExternos.Paginas.

NomePagina

Apenas o nome do objeto Page desejado. Exemplo: PaginaDevBrasil.

 

Titulo

Meramente ilustrativo, este parâmetro recebe uma string que será atribuída ao TabItem que acomodará a Página.

O código do método AbrirPagina() inicia verificando se a página solicitada já está carregada no TabControl. Se for encontrada, o TabItem que contém a página é selecionado. Quando a página não é encontrada, o método se encarrega de criar um novo TabItem para acomodar a nova página.

Cabe aqui explicar que os objetos Page não podem ser atribuídos diretamente ao TabItem, devemos criar um objeto Frame. A propriedade Source do objeto Frame é responsável por acomodar o objeto Page desejado. Posteriormente, o objeto Frame deve ser atribuído à propriedade Content do TabItem. É mais simples do que parece, e você pode conferir o código no Quadro 2.

private void AbrirPagina(string _Assembly, string _NomePagina, string _Titulo)
{
    tabConteudo.Items.Refresh();
 
    bool founded = false;
 
    try
    {
        Cursor = Cursors.Wait;
 
        foreach (TabItem item in tabConteudo.Items)
        {
            if (item.Name == "tab" + _NomePagina)
            {
                tabConteudo.SelectedItem = item;
                founded = true;
            }
 
            if (founded) break;
        }
 
        if (!founded)
        {
            TabItem newTab = new TabItem();
 
            newTab.Name = "tab" + _NomePagina.Replace("/"string.Empty);
            newTab.Header = _Titulo;
 
            Frame NovaFrame = new Frame();
 
            NovaFrame.Background = Brushes.Gainsboro;
            NovaFrame.Source = new 
Uri("pack://application:,,,/" + _Assembly + ";component/" + _NomePagina + ".xaml"UriKind.Absolute);
            newTab.Content = NovaFrame;
 
            this.tabConteudo.Items.Add(newTab);
 
            tabConteudo.SelectedItem = newTab;
 
        }
 
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        Cursor = Cursors.Arrow;
    }
}


Quadro 2: Implementando o método AbrirPagina()

Para invocar o método AbrirPagina() você só precisa passar os parâmetros requeridos. O código apresentado a seguir demonstra como usar este método para abrir a página DevBrasil encapsulada no assembly ObjetosExternos.

private void btnDevBrasil_Click(object sender, RoutedEventArgs e)
{
    AbrirPagina("ObjetosExternos""PaginaDevBrasil""DevBrasil");
}


Quadro 3: Invocando o método AbrirPagina() 

O método AbrirJanela()

O próximo a ser analisado é o método AbrirJanela(). Neste método, usamos o objeto Type para obter uma instância da Janela desejada. Um teste lógico simples se encarrega de verificar se os parâmetros informados correspondem a um tipo existente, caso o método GetType retorne valor Nulo, o procedimento é abortado. Quando o objeto é válido, o método CreateInstance do objeto Activator é usado para instanciar a Janela. É necessário fazer um casting da nova instancia antes de atribuí-la para a variável do tipo Window. O Quadro 4 apresenta este método.

private void AbrirJanela(string _Assembly, string _NomeJanela)
{
    Type t = Type.GetType(_Assembly + "." + _NomeJanela + "," + _Assembly);
 
    if (t != null)
    {
        Window w = (Window)Activator.CreateInstance(t);
 
        w.WindowStartupLocation = WindowStartupLocation.CenterScreen;
 
        w.ShowDialog();
    }
}


Quadro 4: O método AbrirJanela()

Para invocar o método AbrirJanela() basta informar os dois parâmetros requeridos. Veja o exemplo a seguir.

private void btnAbrirJanelaExterna_Click(object sender, RoutedEventArgs e)
{
    AbrirJanela("ObjetosExternos""JanelaExemploImagem");
}


Quadro 5: Invocando o método AbrirJanela()

Carregando Imagens Externas

Finalmente, vamos entender como atribuir uma imagem armazenada num assembly externo para a propriedade Source do controle Image. A classe Uri é utilizada para esta finalidade. Para entender melhor este conceito, pesquise na documentação do Visual Studio a expressão “Pack URIs in WPF”. Confira o código a seguir.

private void btnImagemSeattle_Click(object sender, RoutedEventArgs e)
{
    imgExemplo.Source = new BitmapImage(
new Uri("pack://application:,,,/BibliotecaImagens;component/JPG/Seattle.jpg"));
}


Quadro 6: Carregando imagens externas

Conclusão

Neste artigo você aprendeu como encapsular e consumir imagens, janelas e páginas em assemblies externos. Aprofunde seus conhecimentos sobre este tema visitando a comunidade WPF.

Faça o download deste artigo no formato PDFe também do código-fonte deste exemplo.

 

Posted: Sun, Feb 20 2011 8:41 by Carlos Mattos | with no comments
Filed under: , ,
Quarta Tecnológica em Sorocaba

Direcionada para os empresários e empreendedores do segmento de Tecnologia da Informação, a Prefeitura Municipal de Sorocaba realiza nesta quarta-feira, dia 23/02/2011, a Quarta Tecnológica. O evento é gratuito (vagas limitadas), será realizado no Auditório da Biblioteca Municipal "Jorge Guilherme Senger", e abordará em seus dois temas principais, a Cultura da Inovação e Como e Onde Conseguir Recursos para Inovação. Para garantir sua reserva, ligue para (15) 3237-9087 ou envie e-mail para: michel.podisorocaba@gmail.com.

More Posts Next page »