Programa de Formação.NET

Tamanho: px
Começar a partir da página:

Download "Programa de Formação.NET"

Transcrição

1 Programa de Formação.NET

2 Índice Capítulo 1 Introdução 9 Capítulo 2 Visão Geral do.net 9 Estratégia.NET...9 Tecnologias...11 Vantagens do.net...12 Desvantagens do.net...13 Versões do Framework...13 Framework.NET Versão 1.0 ( ) 14 Framework.NET Versão 1.1 ( ) 14 Framework.NET Versão 2.0 ( ) 14 Funcionamento do Framework...15 A Máquina Virtual...15 Esquema de funcionamento do.net. 16 Coleta de lixo (Garbage Collector)...17 Capítulo 3 Visual Studio Objetivos...19 Conceitos de Solução e Projeto...19 Breve Introdução aos Diferentes Tipos de Projeto...20 Explorando as Janelas...22 Solution Explorer...22 Toolbox...23 Properties...23 Server Explorer...24 Task List...24 Output...25 Error List...25 Lab: Navegando na IDE...25 Revisão...28 Capítulo 4 Linguagem C# 29 Declaração de Variáveis

3 Case Sensitive...29 Tipos de variáveis...29 Marcadores de bloco e finalizadores...32 Símbolos e operadores lógico-aritméticos...32 If...else...33 Laços While...33 Laços for...33 Laços do...while...34 Switch..Case...34 Loop foreach...34 Vetores (arrays)...35 Funções...35 Estrutura de um programa C#...36 Conversão de tipos (cast)...36 Strings...37 Revisão...37 Capítulo 5 Orientação a Objetos com C# 38 Objetivos...38 Visão Geral...38 Classes e Objetos...39 Agora que criamos a classe porta, como fazemos para criar um objeto do tipo Porta? 40 Atributos e Propriedades...40 Métodos...41 New Keyword...42 Construtores e Destrutores...43 Lab: Trabalhando com Classes...44 Níveis de Acesso e Visibilidade...47 Public...48 Private...48 Protected...48 Internal...49 Protected Internal

4 Resumo dos Níveis...49 Encapsulamento...50 Notação UML...50 Herança...51 Classe Abstrata e Classe Selada...53 Sobrescrita de Métodos...54 Sobrecarga de Métodos...55 Acessando a classe pai base e this...55 Polimorfismo...55 Lab: Trabalhando com Herança...57 Interface...57 Métodos, Atributos e Propriedades Estáticas...58 Classes Parciais...59 Revisão...60 Capítulo 6 Tópicos Avançados 61 Objetivos...61 Namespaces...61 Outro uso para Using...63 São idênticas! 63 Referências...64 Lab: Trabalhando com Namespace e Referências...65 Bibliotecas do Framework.NET O namespace System...67 Nota 68 O namespace System.Text...68 O namespace System.Collections...68 Trabalhando com HashTables 69 O namespace System.IO...70 Escrevendo um arquivo 70 Lendo um arquivo 70 Tarefas recorrentes...70 Acessando o diretório da aplicação...70 Verificando o nome do computador

5 string NomeComp = System.Environment.MachineName; 70 string ndns = System.Net.Dns.GetHostByName("LocalHost").HostName; 71 Verificando a versão do sistema operacional...71 Verificando o usuário que está rodando o programa...71 string usr = System.Environment.UserName; 71 Tratamento de Erros Uso de Try/Catch/Finally...71 Tratamento estruturado de erros try/catch...71 Exceções personalizadas...74 Disparando exceptions...74 Finally...74 Revisão...75 Capítulo 7 XML 76 Objetivos...76 O que é XML?...76 Elementos de um Documento XML...77 Declaração...77 Tags...77 Atributos...79 Comentários...79 XML Bem Formado...79 Definindo a Estrutura do Documento...79 Revisão...81 Capítulo 8 ADO.NET 82 Objetivos...82 O que é o ADO.NET...82 Providers do.net...82 Modelo ADO.NET...83 Connection...83 Command...83 DataReader...84 DataAdapter...85 Criando comandos automaticamente: o CommandBuilder...86 DataSet...87 Nota 87 5

6 Populando e iterando por um DataSet...88 Filtrando dados em um DataSet...88 Procurando por uma informação em um DataSet...89 DataViews...89 Nota 89 Atualizando o banco com informações do DataSet...90 Acessando arquivos XML...91 Gravando arquivos XML a partir de um DataSet...91 Lendo arquivos XML em um Dataset...92 Trabalhando com nulos...93 Revisão...93 Capítulo 9 Trabalhando com Windows Forms 94 Objetivos...94 Formulários MDI...94 Herança de formulários...95 Nota 95 User Controls...96 Adicionando um controle programaticamente...96 Disparando eventos de um controle...96 Lab: Criando um User Control...97 Respondendo a eventos de teclado Data Binding DataSource DataBinding BindingNavigator Lab: Data Binding DataGridView Populando um DataGridView Ativando a ordenação automática Ativando o auto-ajuste de linhas e colunas Renomeando as colunas Formatando colunas Mudando o estilo de acordo com uma condição Fazendo um DataGridView zebrado Lendo eventos de seleção

7 Oferecendo uma lista de opções em um ListBox Formulários Master/Detail DataRelation Estratégia do Master/Detail Lab: Relacionamentos e Master-Detail Revisão Capítulo 10 Web Services 118 Objetivos Conceito: O que é um Web Service? Criando um Web Service Consumindo um Web Service Distribuindo um Web Service Revisão Capítulo 11 Depuração, Debug e Trace 130 Objetivos Depurando uma aplicação Breakpoints e condições Watch Window O QuickWatch A janela Output A janela Immediate As janelas Locals e Auto Debug e Trace Métodos do Debug e do Trace Listeners Revisão Capítulo 12 Distribuição 138 Objetivos Tipos de setup suportados Criando um projeto de setup Personalizando o setup Seção File System Seção Registry Seção File Types

8 Seção User Interface Seções Custom Actions e Launch Conditions Criando um projeto de atualização Click-once deploy Revisão Apêndice A Referências 150 Livros e Revistas Sites NET e Visual C# Microsoft ASP.NET Site oficial da Microsoft sobre ASP.NET 150 MSDN Brasil Outro site official da Microsoft, trata das plataformas de desenvolvimento Microsoft 150 Visual C# Walkthroughs 150 Code Project 150 C# Reference 150 Windows Forms Introducing a New Data Grid 151 Windows Forms Demos 151 XML XML Tutorial 151 XML Introdução 151 DTD Tutorial 151 XML Schema Tutorial 151 System.Xml Namespace 151 Acessando XML remoto e buscando informações com o Namespace System.Xml.XPath 151 Migrando arquivos Textos delimitados para XML 151 Distribuição

9 Capítulo 1 Introdução Com este intuito, estão sendo desenvolvidos treinamentos, para preparar os profissionais para este o novo conceito de desenvolvimento, que surge junto com o.net. Para que os profissionais tenham condição de compreender esse novo universo introduzido pelo.net, esse Adoption Lab irá discutir os principais conceitos que estão por trás deste. Faremos um tour pelo Visual Studio, e criaremos algumas aplicações usando o C# como base. Terminaremos mostrando como distribuir as aplicações desenvolvidas, e como planejar estratégias de migração. Como a plataforma.net é extremamente rica, e o tempo do curso é limitado, não será possível cobrir tudo o que o.net têm a oferecer. Como essa migração é uma mudança de paradigmas, é necessário cobrir alguns dos aspectos mais importantes da linguagem e do framework como orientação a objetos, acesso a dados através do ADO.NET, XML, Web Services. Procuramos, no material teórico, dar um embasamento maior do que o que será visto em sala, para que o aluno possa por iniciativa própria complementar o conhecimento adquirido em sala. Por fim, esperamos com esse treinamento plantar uma semente, que instigue os profissionais a buscar conhecer mais sobre esse assunto. Para auxiliá-los, indicamos algumas referências aonde é possível iniciar a sua pesquisa. Capítulo 2 Visão Geral do.net Estratégia.NET A Microsoft vem constantemente evoluindo as tecnologias de desenvolvimento, buscando integrar aplicações e tornar o desenvolvedor mais produtivo. Com o aparecimento do DDE e OLE, a Microsoft permitiu a integração fácil entre aplicações Office e programas desenvolvidos dentro do ambiente Windows. 9

10 O ActiveX veio no bojo da Internet, oferecendo para os programadores os conceitos de componentização. A tecnologia COM trouxe maior liberdade de desenvolvimento, e a COM+ introduziu um framework que permite escalabilidade, transações e segurança. Apesar dessas mudanças, ainda existia um grade vazio a ser preenchido. Era custoso para um programador Visual Basic desenvolver componentes que usassem todos os recursos da tecnologia COM, bem como fazer uso da API: a documentação disponível era voltada a programadores C++, e a principal fonte de informação eram livros que traduziam as interfaces da API para que os programadores VB pudessem utilizar. Além disso, ainda havia o problema de tipos de dados que as interfaces usavam e que não estavam disponíveis no VB. Mesmo com os avanços trazidos pelas tecnologias citadas, os programadores Windows ainda enfrentavam outro problema: o famigerado DLL Hell - sobreposição de versões de DLLs em cujas novas versões haviam chamadas de funções diferentes das anteriores, o que fazia com que programas que usavam a versão mais antiga da DLL deixassem de funcionar. Outra característica que foi perdida foi a capacidade de instalar uma aplicação apenas com a cópia dos arquivos: tornou-se necessário o uso de instaladores que, além de copiar os arquivos, ainda precisavam registrar os componentes no Registro do Windows. O.NET não só resolve tais problemas, mas também unifica a plataforma de desenvolvimento e adiciona novas funcionalidades que são ou serão essenciais para o desenvolvimento corporativo, como XML, Web Services, threading, SmartClients e outros. Ele permite que diversas linguagens trabalhem juntas, de forma transparente, para criar aplicações que são mais fáceis de fazer, gerenciar, distribuir e integrar com outros sistemas. Entre suas características, temos: Interoperabilidade Como diversas bibliotecas COM já haviam sido criadas, o.net Framework provê meios de permitir interoperabilidade entre o novo código e bibliotecas existentes. 10

11 Common Runtime Engine As linguagens de programação no.net Framework compilam o código em uma linguagem intermediária conhecida com Common Intermediate Language (CIL). Durante a execução, essa o arquivo no formato CIL é compilada pelo Just In Time Compiler (JIT) em código nativo. A combinação desses conceitos é chamada Common Language Runtime (CLR). Independência de Linguagem O.NET Framework suporta o desenvolvimento em múltiplas linguagens de programação. Isso é possível porque todas as linguagens devem converter seu código em um código que atenda aos requisitos da MSIL. Base Class Library (BCL) A BCL (também conhecida como Framework Class Library - FCL), é uma biblioteca de classes disponível a todas as linguagens que utilizam o.net Framework. Ele prove um conjunto de classes que encapsulam funções comuns, como: acesso a arquivo, interação com banco de dados, manipulaçãp XML, etc. Distribuição Simplificada Instalação e distribuição de aplicações Windows foi simplificada. Manipulação de Registry, distribuição de arquivos, registro de DLLs foram quase completamente eliminadas pelos novos mecanismos de distribuição do.net. Segurança O Framework.NET permite ao código rodar com diferentes níveis de confiabilidade. Tecnologias O.NET engloba diversas tecnologias: Windows Forms Permite o desenvolvimento de aplicações para Windows, incluindo elementos comuns de interface com o usuário; Windows Services Permite o desenvolvimento de serviços para Windows. 11

12 ASP.NET Foi a tecnologia escolhida pela Microsoft para substituir as antigas páginas ASP. Permite ao desenvolvedor desenvolver aplicações web, usando todas facilidades do BCL, além de diversos controles que reduzem drásticamente o tempo de desenvolvimento de qualquer aplicação Web. ADO.NET O ADO.NET é a nova versão o ActiveX Data Objects (ADO) para.net. Ele simplifica o acesso a dados, e permite o acesso desconectado..net Remoting Corresponde a uma nova abordagem de comunicação entre processos. Provê um rico e extensível framework para comunicação entre diversas aplicações, rodando em diferentes domínios de aplicação. Web Services Utilizando SOAP, XML, e os conceitos de Service Oriented Architecture (SOA), um web services permite conexão entre aplicações através da internet. Mobille Applications Utilizando-se do Compact Framework, é possível desenvolver de forma transparente aplicações para Pocket, SmartPhone, e outros dispositivos compactos. Visual Studio Tools for Office (VSTO) Com o VSTO, é possível desenvolver aplicações que utilizem a riqueza da interface com o usuário do Office, e o poder e a robustez das aplicações.net. Vantagens do.net A plataforma.net traz vantagens interessantes, tais como: Conjunto rico de bibliotecas com os mais variados usos; Controle de versão: fim do DLL Hell ; Facilidade de desenvolvimento de aplicações desde as simples até as mais complexas; Facilidade na instalação e na distribuição de aplicações; 12

13 Orientada a objetos; ADO.NET trabalha com dados desconectados; Alta escalabilidade para ambientes de missão crítica; Interoperabilidade entre plataformas e componentes desenvolvidos em outras linguagens.net; Sintonizado com as últimas tecnologias; Solução sendo mundialmente adotada; Tecnologia baseada em máquina virtual; Rotina automática de coleta de lixo que permite remoção de variáveis e objetos que não são mais utilizados; Novo ambiente de desenvolvimento acelerado (RAD). As vantagens não acabam por aqui, seriam necessárias páginas e páginas para conseguir chegar a uma lista mais completa. Mas a lista acima já é um tanto agradável. Desvantagens do.net As maiores desvantagens do.net, que devem ser vistas para se ter uma idéia do esforço de migração: É um novo paradigma, e requer aprendizado de novas técnicas para fazer o melhor uso da ferramenta; Requer a distribuição do framework; Em alguns casos requer reengenharia ou reescrita completa do código. Versões do Framework Existem diferentes versões do Framework: 13

14 Framework.NET Versão 1.0 ( ) Esta foi a primeira versão do Framework, liberado em Ele está disponível como um pacote de distribuição, como um kit de desenvolvimento de software (SDK), ou junto com o Visual Studio Framework.NET Versão 1.1 ( ) Este foi o primeiro grande upgrade, liberado em Ele está disponível como um pacote de distribuição, como um SDK ou junto com o Visual Studio Além disso, ele acompanha o Windows Server Mudanças da versão 1.0 Suporte nativo a aplicações mobile (na versão 1.0, era disponível como um Add-On). Mudanças em Segurança permite a assemblies Windows Form executarem em um modo semi-confiável Suporte nativo a bancos ODBC e Oracle (na versão 1.0, era disponível como um Add-On)..NET Compact Framework Uma versão de Framework para aparelhos como Pocket e SmartPhone. Suporte ao Internet Protocol v6 (IPv6). Numerosas mudanças em APIs. Framework.NET Versão 2.0 ( ) Nesta versão, liberada em Outubro de 2005, houveram alterações não só de tecnologia, como de estratégia. Ele está disponível como um pacote de distribuição, como um SDK ou junto com o Visual Studio 2005 ou o SQL Server Mudanças da Versão 1.1 Numerosas mudanças em APIs. 14

15 Novos controles ASP.NET. Versão interna de IIS, permitindo desenvolver aplicações ASP.NET ou Webservices sem a necessidade de ter o IIS instalado na máquina de desenvolvimento. Suporte completo a 64-bits para as plataformas x64 e IA64. Suporte de linguagem para Generics diretamente na CLR. Funcionamento do Framework A Máquina Virtual O.NET baseia-se no conceito de máquina virtual, que serve como uma camada que fica entre o código e o sistema operacional. No conceito de máquina virtual, um programa pode ser portado entre várias plataformas, desde que exista para elas uma máquina virtual capaz de compilar o código. Além do pacote de instalação comum para Windows, a Microsoft provê o Shared Source Common Language Infraestructure, que roda em Windows, FreeBSD e Mac OS X; e como o CLI é um padrão aberto, existem diversos projetos open source que surgiram para prover suporte para plataformas adicionais, sendo o mais conhecido o Mono. Todo código escrito em.net (usando Visual Basic, C#, J# ou qualquer outra linguagem disponível) é compilado para uma linguagem intermediária, chamada CIL (ou MSIL). O código CIL é então distribuído e executado pelos clientes e usuários da aplicação. Os leitores mais atentos podem estar pensando: - Mas é idêntico ao que o VB 6 já fazia: o código é traduzido em tokens que são interpretados. Aí é que reside a grande diferença: o código.net é compilado just-in-time pela máquina virtual, ou seja, é gerado de fato código de máquina que é executado com extrema rapidez. No VB 6, o código era interpretado pelo VBRun: a cada instrução o interpretador comandava instruções para o processador mas se, por exemplo, uma função for chamada repetidas vezes, ela serão reinterpretada a cada chamada que for feita. 15

16 As grandes vantagens de se fazer a compilação just-in-time são a compilação específica para o hardware em que a Máquina Virtual roda, e a portabilidade, já mencionada. Como todo o código é traduzido para a linguagem intermediária, tornou-se fácil padronizar tipos de dados, bibliotecas, classes, componentes, que passam agora a ser especificamente.net e facilmente utilizáveis em qualquer linguagem.net, seja ela C++, Visual Basic ou C#. À esse conjunto de bibliotecas, deu-se o nome de Base Class Library (BCL) - também conhecida como Framework Class Library (FCL). A BCL prove um conjunto de classes que encapsulam funções comuns, como acesso a arquivo, interação com banco de dados, manipulaçãp XML, etc. O esquema abaixo detalha as camadas da Máquina Virtual: Esquema de funcionamento do.net. As caixas superiores (C# e VB.NET) representam o código que é escrito por programadores, como por exemplo MeuPrograma.cs (em C#) ou MeuPrograma.vb (em Visual Basic. NET). 16

17 Para cada linguagem há um compilador específico, que traduz o código escrito para a linguagem intermediária (CIL). O compilador específico do Visual Basic é o vbc.exe (de Visual Basic Compiler). O código CIL gerado é então armazenado, junto com outras informações, em um arquivo.exe ou.dll, dependendo do que for parametrizado na chamada do vbc.exe. O Visual Studio já faz essa tarefa de chamar o vbc.exe com os parâmetros corretos ao se usar qualquer uma das opções de Build e Run. A caixa CLR representa a Máquina Virtual (CLR de Common Language Runtime), que é responsável pelo gerenciamento dos objetos.net e pela chamada do compilator just-in-time (JIT), que compilará o código em linguagem de máquina. O código compilado ficará então em cache até que o Windows seja desligado ou reiniciado, ou ainda quando a Máquina Virtual necessitar de recursos. Coleta de lixo (Garbage Collector) O.NET possui um mecanismo interno de coleta de lixo, capaz de desalocar a memória ocupada por objetos que já não estão mais sendo usados. Além de retirar do programador a preocupação de limpeza de recursos, a coleta de lixo também resolve os problemas de desalocação de referências circulares e de dependência de objetos que esporadicamente aconteciam no COM. A limpeza era feita atribuindo-se Nothing à uma variável de referência mas, se essa variável apontasse para um objeto que, internamente, também tivesse referência a outros objetos, estes últimos não seriam liberados se o programador não tomasse os cuidados necessários. A coleta de lixo é feita sem que o usuário tenha que intervir, e o framework decide qual o melhor momento em que ela ocorrerá, usando parâmetros como escasseamento de recursos (caso o sistema passe por situações de falta de memória) ou ociosidade de CPU (quando o.net usa ciclos ociosos para alocar suas threads de limpeza). A coleta de lixo é baseada em um contador de referências que é uma característica de cada objeto. Quando o.net detecta um objeto cujo marcador de referências 17

18 contém zero, isto é, não existe nenhum outro objeto que o referencia, ele é colocado em uma fila e será posteriormente eliminado. Há meios de se lidar com o mecanismo de coleta de lixo, como o método GC.Collect(), mas é usada em casos específicos aonde se termina de usar objetos muito grandes que, no entender do programador, devem ser liberados rapidamente. No geral, deve se deixar o mecanismo de coleta de lixo realizar a sua tarefa automaticamente. 18

19 Capítulo 3 Visual Studio 2005 Objetivos O objetivo deste capítulo é familiarizar o leitor com o ambiente de desenvolvimento integrado (IDE) do Visual Studio Conceitos de Solução e Projeto O projeto é o ponto de partida para o desenvolvimento de aplicações, componentes e serviços no Visual Studio.NET. Ele age como um container, que gerencia seu código fonte, conexões de dados, arquivos e referências. Um projeto é organizado como parte de uma solução, a qual pode conter múltiplos projetos, que são interdependentes entre si. O Visual Studio usa um modelo baseado em pastas todos os itens do projeto são colocados na hierarquia da pasta do projeto. Quando você adiciona um arquivo 19

20 texto, uma cópia do arquivo é adicionada à pasta do projeto. Além disso, quando você remove um arquivo, você exclui o arquivo fisicamente. Os projetos são agrupados em soluções, que podem conter até projetos de linguagens diferentes. No Visual Studio.NET, os arquivos de projeto (.vbproj,.csproj, etc) e os arquivos de solução (.sln) estão no formato XML. Breve Introdução aos Diferentes Tipos de Projeto Na tela inicial do Visual Studio, quando você seleciona File > New, você já possui alguns tipos diferentes de opções a seguir: Project Web Site Ambos referem-se a projetos. Entretanto, o primeiro grupo corresponde aos projetos aplicados a soluções desktop, e o segundo grupo aos projetos desenvolvidos para Internet. Essa separação foi introduzida apenas na versão Ao selecionarmos uma das opções (Project ou Web Site), será exibida uma tela na qual poderemos visualizar os outros tipos de projetos disponíveis. 20

21 Ao selecionarmos File > New > Project, visualizamos a tela acima. Em Project types, podemos ver os tipos de projeto disponíveis agrupados por categoria (por exemplo, Linguagem, ou se é aplicação Windows ou para Smart Devices). Se quisermos criar uma solução em branco, devemos selecionar Other Project Types > Visual Studio Solutions > Blank Solution. Isso irá criar uma solução em branco. A partir desta, poderemos adicionar novos projetos no futuro. Entretanto, quando criamos um novo projeto, uma solução é automaticamente criada, com o mesmo nome da solução que você criou. Alguns tipos de projeto disponíveis: Blank Solution Como o nome diz, cria uma solução em branco. Windows Application Cria uma aplicação executável, que usa como interface formulários Windows (Windows Forms). Console Application Cria uma aplicação executável, que usa como interface a linha de comando. Class Library Cria um projeto que será compilado em uma biblioteca (DLL) de classes. 21

22 Windows Control Library Cria um projeto que abriga uma biblioteca (DLL) de controles que podem ser adicionados aos formulários Windows. Windows Service Cria uma aplicação executável que roda como um serviço no Windows. Device Application Cria uma aplicação executável, desenvolvida para dispositivos compactos. Setup Project Cria um instalador para outras aplicações. Setup Wizard Cria um instalador para outras aplicações, utilizando um Wizard de aplicações. Visual Studio Add-In Permite desenvolver aplicativos que irão customizar o ambiente do Visual Studio. Test Project Cria um projeto que executa testes na sua aplicação. Além disso, em File > New > Web Site, temos os seguintes projetos: ASP.NET Web Site Cria um projeto de um web site, utilizando ASP.NET. ASP.NET Web Service Cria um projeto de um web service, utilizando ASP.NET. Estes são apenas alguns exemplos de projetos disponíveis. Além disso, alguns plug-ins para o Visual Studio instalam outros templates de projeto. Explorando as Janelas Solution Explorer A janela Solution Explorer permite visualizar a estrutura de arquivos de nossa solução, os projetos contidos nesta, e os arquivos contidos em cada projeto. Para facilitar a programação, ela agrupa arquivos similares (como, por exemplo, o arquivo que representa a planilha e os arquivos de código por trás desta) e oculta os que não fazem parte da solução. 22

23 Toolbox Esta janela é utilizada em modo de design, e agrupa todos os controles que podem ser adicionados ao seu projeto. Basta arrastar um controle para o design, para que o código produzido pela inserção desse controle seja automaticamente gerado. Properties Nesta janela, você pode alterar as propriedades de controles, formulários, páginas etc, em modo de Design. Além disso, você pode verificar os eventos acionados por cada controle. 23

24 Server Explorer Esta janela permite gerenciar diversos recursos, como conexões de dados, o event log do Windows, filas de mensagem, lista de serviços, etc. Como a ToolBox possui uma abordagem Drag-and-Drop, permite você inserir objetos em modo de design, inserindo em seu projeto objetos que permitem se comunicar com os recursos do sistema. Task List Permite ao desenvolvedor visualizar comentários e tarefas, deixados por ele mesmo ou por outro desenvolvedor. Para criar um comentário, basta usar a seguinte sintaxe: // TODO: Implementar acesso de usuário. Todos os desenvolvedores que abrirem a Task List, verão que na linha x do arquivo y, existe este comentário. 24

25 Output Na janela Output é mostrada a saída do console. Ali é possível ver não só o progresso da compilação, mas também todas as mensagens que são enviadas ao console como, por exemplo, System.Console.Write(). Error List Nesta janela, é possível verificar erros, warnings e mensagens geradas pelo compilador durante a compilação de nosso código. Lab: Navegando na IDE Vamos começar a explorar a IDE do Visual Studio, criando um novo projeto e uma solução. Abra o Visual Studio Em File > New, selecione a opção Project. Em Project Types, selecione Visual C# > Office. Em Project Templates, selecione Windows Application. 25

26 Devemos dar um nome para a nossa aplicação. Na caixa Name, escreva WindowsApplicationCS, em Location, digite C:\LabVS, e em Solution Name deixe o nome proposto. Como não estaremos trabalhando com controle de versão, deixe a caixa Add to Source Control desativada. Entretanto, deixe a caixa Create directory for Solution ativada (ele irá criar uma pasta para a Solução, separada da pasta do projeto). Clique em OK. A estrutura criada pelo projeto no disco ficou da seguinte forma: Voltando agora ao Visual Studio, abra a janela ToolBox, expanda All Windows Forms, e arraste um controle do tipo Button da ToolBox para a planilha. 26

27 Clique com o botão direito no botão, e selecione Propriedades. Na janela de propriedades, busque e altere os seguintes campos: Campo (Name) Text Valor btnhelloworld Hello World! Feito isso, clique 2 vezes no botão. No evento que trata o click do botão, escreva o seguinte trecho de código: MessageBox.Show("Hello World!"); Agora, você deve ter o seguinte trecho de código: namespace WindowsApplicationCS public partial class Form1 : Form public Form1() InitializeComponent(); private void btnhelloworld_click(object sender, EventArgs e) MessageBox.Show("Hello World"); Rode sua aplicação, clicando no ícone verá o formulário. Clique no botão.. A sua aplicação será executada, e você Grave as alterações efetuadas, e feche o Visual Studio. 27

28 Revisão Esperamos, neste ponto, que o leitor tenha se familiarizado com a interface do Visual Studio 2005, e seja capaz de criar um novo projeto. O projeto criado nessa sessão será utilizado como base nas sessões seguintes. 28

29 Capítulo 4 Linguagem C# Declaração de Variáveis No C# as variáveis são declaradas ao longo do código e o tipo vem antes do nome da variável. Dessa forma, temos: C#: int a; string b; Case Sensitive O C# é case sensitive. O que isso significa? Vejamos um exemplo: int teste = 0; int Teste = 0;...neste caso, as variáveis teste e Teste são duas variáveis diferentes! Além disso, supondo que temos uma variável carro... string carro;...não podemos acessá-la como Carro, CARRO, etc. O único modo de acessála é através de: carro = 2; Tipos de variáveis O Common Type System (CTS) define como os tipos são declarados, utilizados e gerenciados em tempo de execução, e também é uma parte importante do suporte do runtime de intregração entre linguagens. O CTS realiza as seguintes funções: Estabelece um framework que auxilia a integração entre linguagens, segurança de tipos, e alta performance de execução de dados; 29

30 Provê um modelo de orientação de objetos que suporta a implementação completa de muitas linguagens de programação. Define as regras que as linguagens devem seguir, o que ajuda a garantir que objetos escritos em diferentes linguagens possam interagir entre si. Os principais tipos existentes no C# estão contidos na tabela abaixo. Na tabela, os valores entre parênteses representam as classes bases do tipo. Quando não houver um valor entre parênteses, indica que o nome da classe é o mesmo do nome do tipo do C#. Categoria Tipo do C# Alocação Memória Booleano Bool Depende plataforma Range valores True ou False. Inteiro byte 1 byte 0 a 255 (sem sinal). sbyte 1 byte -128 a 127 (com sinal). Não é compatível com a CLS. short (Int16) 2 bytes a (com sinal). int (Int32) 4 bytes a (com sinal). long (Int64) 8 bytes a (com sinal). ushort (UInt16) 2 bytes 0 a (sem sinal). uint (UInt32) 4 bytes 0 a (sem sinal). ulong (UInt64) 8 bytes 0 a (sem sinal). Ponto Flutuante float 4 bytes x10 38 a x10-45 para valores negativos; x10-45 a 30

31 x10 38 para valores positivos. decimal 16 bytes Um decimal de 128-bits, representando valores variando de 1.0x10-28 a 7.9x10 28, com dígitos significantes. double 8 bytes x a x para valores negativos; x a x para valores positivos. Outros char 2 bytes Um caracter unicode de 16- bits. DateTime 8 bytes Um tipo que representa um valor de data e hora. Ele armazena os valores em incrementos de 100 nanosegundos de tempo passado desde 12:00 AM de 1/1/1 do calendário Gregoriano. IntPtr UIntPtr Objetos Object 4-bytes em plataforma 32- bits; 8-bytes em Um inteiro com sinal cujo tamanho varia de acordo com o sistema (32-bits em um plataforma 32-bits, e 64- bits, em uma plataforma de 64-bits). Um inteiro sem sinal cujo tamanho varia de acordo com o sistema (32-bits em um plataforma 32-bits, e 64- bits, em uma plataforma de 64-bits). Não é compatível com CLS. A raiz da hierarquia de objetos, qualquer tipo pode ser adicionado em um tipo objeto. 31

32 plataforma 64- bits. string Varia Uma string de tamanho fixo de caracteres unicode. Os tipos básicos estão contidos na biblioteca System (veremos bibliotecas nos capítulos seguintes). Marcadores de bloco e finalizadores No C#, o marcador de bloco são as chaves ( e ) e as sentenças são terminadas com ponto-e-vírgula. C#: a = 10; b = 11; c = a + b; Símbolos e operadores lógico-aritméticos Como pode ser observado no exemplo acima, o operador de atribuição do C# é o sinal de igual. A tabela abaixo lista símbolos e operadores: Símbolo/operador C# Atribuição = Igual (Comparação) == Diferente (Comparação)!= And lógico && Or lógico Not lógico! Incremento x++ 32

33 Decremento x-- If...else No C#, a condição comparada sempre deve vir dentro de parênteses e, por isso, existe um delimitador que informa aonde começa uma condição e aonde ela termina. Assim sendo: C#: if (x > 7) y = x 6; else y = x; Laços While O while, seguindo a mesma idéia de colocar a condição dentro de parênteses: C#: while (x > 7) x++; Laços for Os laços for nada mais são um laço while aonde é possível: declarar/inicializar uma variável contadora; verificar uma condição de saída; incrementar/decrementar a variável contadora. Como exemplo de cada uma dessas funcionalidades, temos: for (int i =0 ; i <= 10 ; i++) Temos aí uma inicialização (int i =0) e uma condição de parada (i <= 10), ao final de cada interação é executado incremento (i++). 33

34 Laços do...while O laço do..while, vale para a mesma regra para a condição de loop do while: a condição deve estar entre parênteses. C#: exit = false; do a = a + 1; if (a > 99) exit = true; while (! exit); Switch..Case A instrução Switch..Case do C#, agrega várias comparações simples, poupando o desenvolvedor de usar vários if encadeados: C#: switch (i) case 1: Opcao = "1 prestação"; break; case 2: Opcao = "2 prestações";break; case 3: Opcao = "3 prestações";break; default Opcao = "Pagamento no ato";break; Algumas observações importantes sobre o switch: todas as opções devem terminar com break ou goto; não é possível trabalhar com intervalos; o switch aceita usar strings no case. Loop foreach É uma alternativa interessante e muito usada para iterar por listas, coleções ou vetores: com o foreach não é necessário buscar dados de tamanho e índice inicial para que possa ser feito um laço for trivial. O foreach se encarrega de controlar 34

35 esses dados, deixando o desenvolvedor livre para implementar outras funcionalidade sem se preocupar com o controle desse loop. O exemplo abaixo ilustra o seu uso: static void Main(string[] args) foreach (string str in args) Console.WriteLine(str); A declaração static void Main é usada em C# para indicar que aquela é a função a ser chamada quando o programa for iniciado. string[] args é o vetor dos argumentos de linha de comando. A função acima itera por cada argumento de string[] args. A cada iteração, o valor correspondente do vetor é armazenado na variável str e é impressa na saída do console. Vetores (arrays) Os vetores no C# são declarados junto com a variável e têm sempre índice inicial zero. As diferentes formas de declarar são: C#: int[] pontos; int[10] outrospontos; int[,] plano; Funções No C# tanto procedures como functions são funções, e são diferenciadas pelo tipo do retorno: se forem void, as funções são tratadas como procedures, se tiverem qualquer outro tipo, são tratadas como functions. Por exemplo: C#: void Executa(int codigo); double Calcula(int Codigo, double passo); 35

36 Estrutura de um programa C# No C# o desenvolvedor não fica restrito às áreas de declaração: variáveis e métodos podem ser declarados ao longo do código, e não em uma seção específica. O desenvolvedor pode declarar no início as variáveis e se disciplinar para isso, mas a linguagem não o obriga a tal. A seção using do C#, deve vir sempre no início do código. using System; public class MinhaClasse public int MinhaFuncao(int Entrada); // só a assinatura, implementada abaixo public void MinhaProcedure() // implementação public int MinhaFuncao(int Entrada) // implementação Conversão de tipos (cast) No C# deve ser usada a notação abaixo para a convesão: Sendo assim: (<tipo de destino>) variável public int SomaInteiros(Double par1, par2) return (int)par1 + (int)par2; Para converter para strings, pode ser usado o método ToString: public string SomaInteiros(Double par1, par2) int soma soma; soma = (int)par1 + (int)par2 return soma.tostring(); 36

37 Strings As Strings do.net merecem atenção especial. As novas strings são Unicode, e ocupam 2 bytes a cada caractere. Ao concatenar uma string com outra, obtemos uma nova string. Por conta disso, o.net foi aparelhado com a classe StringBuilder, contida na biblioteca System.Text. (falaremos mais sobre classes e bibliotecas nos próximos capítulos). A classe StringBuilder deve sempre ser usada em casos na qual existam múltiplas concatenações. Por exemplo: StringBuilder sb = new StringBuilder(); string strfrase; sb.append("a "); sb.append("ligeira "); sb.append("raposa "); sb.append("marrom "); sb.append("ataca "); sb.append("o cão preguiçoso."); strfrase = sb.tostring(); Nota No C#, como já foi falado na seção de conversões, todos os tipos implementam um método chamado ToString. Este método, quando executado, retorna o dado no formato de string, de acordo com o tratamento dado pelo tipo. int var1 = 2; string str = var1.tostring(); // O mesmo que str = 2 Revisão Vimos nesse capítulo, as principais características na sintaxe da programação do C#. Iremos, nos capítulos seguintes, nos aprofundar nos conceitos de Orientação a objetos. 37

38 Capítulo 5 Orientação a Objetos com C# Objetivos A linguagem C# foi criada a partir do zero no surgimento do.net. A Microsoft optou por basear a sua nova linguagem nos conceitos de programação orientada a objetos (OOP), disponíveis nas mais modernas linguagens de programação. O objetivo deste capítulo é apresentar alguns desses conceitos para o leitor (aplicados ao C#), para que seja possível aproveitar ao máximo o potencial dessa linguagem. Conhecer a Orientação a Objetos é uma das tarefas que qualquer desenvolver que ainda não conhece deve fazer. Apesar do C# não obrigar o desenvolvedor a programar usando OOP, ele estará limitando o seu potencial. O assunto de Orientação a Objetos, por si só, já valeria um livro exclusivo e dedicado. Não está no escopo desta Apostila explicar em minúcias as técnicas de orientação a objetos, mas sim mostrar em linhas gerais o que é e como é empregada. A seguir veremos como são implementados os conceitos de OOP no Visual C#. Visão Geral A Orientação a Objetos foi criada em meados da década de 70, mas só se popularizou ao final da década de 90. A Orientação a Objetos é um paradigma que aproxima o modo como enxergamos o mundo real com o modo de programarmos. A programação procedural, realizada até então, tinha como foco a codificação de problemas em uma forma de script, com começo, meio e fim determinados, contendo em seu interior desvios, loops e verificações condicionais. Já a Orientação a Objetos foca na estrutura dos objetos envolvidos no problema e sua relação entre eles. O código procedural fica confinado internamente e é altamente fragmentado em relação à outra tecnologia. 38

39 As maiores vantagens da Orientação a Objetos são: Um sistema OO bem projetado reduz significativamente o custo de manutenção e permite distribuir melhor os trabalhos por uma equipe. Permite melhor compreensão do problema por parte do programador e do analista de negócios. Torna mais fácil a reutilização e a componentização do código. Há também desvantagens que devem ser levadas em conta: É um novo paradigma a ser descoberto. Requer prática para arquitetar soluções. Classes e Objetos Classes são esqueletos ou plantas que especificam objetos. Objetos são entidades que representam entidades do mundo real. Um exemplo rotineiramente estudado em livros é a classe Carro. Um carro pode ter características (como cor, número de portas, tipo de pneus, potência do motor, etc) que chamaremos de atributos - e ações (acelerar, frear, abrir porta, acionar o limpador de pára-brisas, etc) que chamaremos de métodos. Note que, apesar de terem valores diferentes (como, por exemplo, cor diferente), o conjunto de atributos e métodos citados é comum à maioria dos automóveis. Ou seja, existe um conjunto de características que define o que é um carro, uma planta. A esse conjunto de características, damos o nome de classe. Quando os mecânicos da fábrica de automóveis montam um carro (ou seja, fazem uma implementação física do que está contido no papel), ele deixa de ser apenas um modelo, apesar de ainda compartilhar características com outros carros. Ele passa a ser um objeto, algo físico, no qual podemos entrar e andar por aí. Em programação, quando criamos uma instância de uma classe em memória, é como se estivéssemos utilizando a classe como planta para criar um objeto físico. 39

40 Voltando ao exemplo da classe carro, quando instanciamos em memória a classe, dando-lhe atributos como cor = verde, numerodeportas = 4, tipodepneus = asfaltocomum, etc, ela se tornou um objeto, que é a instância de uma classe. Vamos começar o nosso exemplo criando uma classe que representa uma porta: class Porta... Agora que criamos a classe porta, como fazemos para criar um objeto do tipo Porta? Porta porta = new Porta(); Com isso, temos que a variável porta contém uma referência para um novo objeto do tipo Porta. Nas seções seguintes, veremos como criar atributos, propriedades e métodos em uma classe. Atributos e Propriedades Atributos são definidos em uma classe, e guardam valores ou referências. Normalmente, são expressas por substantivos que representam os atributos. No C#, os atributos correspondem às variáveis. Vamos mostrar o seu funcionamento através de mais um exemplo. class Casa Porta porta = new Porta();... O que temos aqui? Criamos uma nova classe Casa, e dentro dela adicionamos um atributo uma porta! Ou seja, toda casa que gerarmos a partir de nossa classe Casa terá uma porta mesmo que sejam portas diferentes. No C#, uma propriedade nada mais é do que um tipo especial de variável que deve ser lida/escrita através de acessores. Isso é feito da seguinte forma: Porta PortaEsquerda get return portaesquerda; set portaesquerda = value; 40

41 Métodos Métodos são as ações que são definidas na classe. Normalmente são expressas por verbos que representam operações que a classe permite executar. Como exemplo, vamos implementar alguns métodos em nossa classe Porta: class Porta string cor; bool fechada; bool trancada; void Abrir() if (! trancada) fechada = false; void Fechar() if (! fechada) fechada = true; void Trancar() if (fechada) trancada = true; void Destrancar() trancada = false; bool VerifTrancada() return trancada; void MudarCor(string novacor) cor = novacor; 41

42 Como pode ser visto no exemplo, existe uma única forma para se declarar um método: [<acesso>] [<retorno>] <nome método> ([<lista de parâmetros>])... Falaremos sobre níveis de acesso ainda neste capítulo. A lista de parâmetros deve obeceder à seguinte estrutura: [ref out] <tipo> <nome parâmetro> [, <lista de parâmetros>] A palavra chave ref, indica que o parâmetro será passado por referência. Um argumento passado por referência precisa antes de tudo ser inicializado. Já a palavra chave out, indica que esse parâmetro é um parâmetro de saída o seu valor não será utilizado no código. Para facilitar a compreensão das diferenças entre passar um valor por parâmetro ou por referências, veremos o exemplo de um método que recebe o comprimento e a largura, e retorna a área do quadrado: double CalculaArea( double comprimento, double largura ) // Declarando variáveis locais. double area; if( comprimento == 0 largura == 0 ) // Se um argumento = 0, não dá para calcular a área. area = 0; else // Calcula a área do retangulo. area = comprimento * largura; return area; New Keyword No C# quando queremos declarar uma variável que aponta para uma classe fazemos da seguinte forma: Util util; 42

43 ...e quando queremos inicializar a nossa variável com uma nova instância, utilizamos à palavra chave New: util = new Util(); Por fim, todas as classes herdam de Object. Construtores e Destrutores E se você precisar criar uma classe que, durante a inicialização de um novo objeto, precise executar algum código? Ou precisar rodar comandos de limpeza, antes de o objeto ser destruído? No C#, como no Delphi, existe o conceito de contrutores e destrutores. Um construtor é acionado, caso exista, quando utilizamos à palavra chave New: util = new Util(); Vamos ver um exemplo. Imagine novamente o caso da porta: class Porta string cor; bool fechada; bool trancada;... Vamos agora imaginar que gostaríamos de ter uma classe Porta que permitisse que, em sua inicialização, fossem atribuídos valores às propriedades fechada e trancada. Para isso, vamos utilizar um construtor. O formato da declaração do construtor é semelhante à declaração de um método, com a diferença que não aceita tipo de retorno e que deve possuir o mesmo nome da classe. Assim sendo, em nosso caso teríamos: Porta( bool fechada, bool trancada ) if( fechada ) Fechar(); else Abrir(); 43

44 if (trancada) Trancar(); else Destrancar(); Quando um objeto não é mais necessário, o Garbage Collector chama o método Finalize para aquele objeto antes de liberar a memória. O método Finalize é chamado destrutor, porque ele realiza tarefas de limpeza, tais como gravar informação de estado, fechar arquivos e conexões com bancos de dados, além de outras tarefas que precisam ser feitas antes de liberar o objeto. No C#, os destrutores não podem ser chamados eles são disparados automaticamente pelo GC. Entretanto, devido à característica não-determinística do GC, não é possível saber exatamente quando o destrutor será acionado. Vamos agora utilizar um destrutor para mudar o valor das variáveis fechada e trancada para false, antes de podermos destruir esse objeto da memória. ~Porta() trancada = false; fechada = false; Lab: Trabalhando com Classes Vamos trabalhar com classes. Abra o Visual Studio Abra o projeto WindowsApplicationCS que criamos anteriormente. Remova o botão Hello World, e adicione 6 botões: (Name) btnabreportaesquerda Text Abre Esq. btnfechaportaesquerda Fecha Esq. btnabreportadireita btnfechaportadireita Abre Dir. Fecha Dir. 44

45 btnacelera btnfreia Acelera Freia Agora, adicione 3 controles Label, com os seguintes textos: Porta Esquerda: Porta Direita: Velocidade: Por fim, adicione mais 3 controles do tipo Label, com os seguintes IDs: lblportaesquerda lblportadireita lblvelocidade Você deve ter algo do gênero: Agora que a parte gráfica de nossa aplicação está pronta, vamos implementar o código. Adicione ao seu projeto uma classe Porta (clique com o botão direito no seu projeto, e selecione Add > New Item, selecione Class, e dê o nome Porta.cs ). Em sua classe, implemente: Atributo fechada indica se a porta está fechada; Atributo trancada indica se a porta está trancada; 45

46 Método Abrir permite a abertura da porta; Método Fechar permite o fechamento da porta; Método Trancar permite trancar a porta, caso esta esteja fechada; Método Destrancar destranca a porta, caso esteja trancada; Método VerifFechada retorna indicador se a porta está ou não fechada; Método VerifTrancada retorna indicador se a porta está ou não trancada; Construtor recebe como parâmetro se a porta está fechada e trancada. Até este momento, o código utilizado é idêntico ao dos nossos exemplos. Vamos agora mudar um pouco. Crie uma nova classe, chamada Carro. Como todo carro tem pelo menos 2 portas, iremos adicionar ao nosso carro 2 atributos do tipo Porta (já criado no começo desse lab), e chamá-los de portaesquerda e portadireita. Adicione também um atributo chamado velocidade, que deve ser capaz de receber um valor inteiro. No construtor da classe, inicialize ambas as portas como abertas e destrancadas, e a velocidade em 0. Agora, crie 2 propriedades, PortaEsquerda e PortaDireita, que irão prover acesso aos atributos respectivos. Por fim, iremos adicionar os seguintes métodos: Acelera(valor) Aumenta velocidade do carro, em incrementos de 10, até 180 Km/hora. Se passar de 180, atribui 180 e retorna um indicador, indicando que a velocidade máxima foi atingida. Freia(valor) Diminui a velocidade do carro em valor, em decrementos de 10, chegando ao mínimo de 0. Se for menor que 0, retorna um indicador que o carro já está parado. 46

47 VelocidadeAtual() Retorna um inteiro, indicando a velocidade atual do carro. Grave as alterações. Nesse ponto, o nosso código está pronto. Vamos agora ligar o formulário com o código. Clique 2 vezes sobre o formulário, em uma região aonde não haja nenhum botão ou label. O Visual Studio irá abrir o modo de código, e criar automaticamente um evento Form1_Load. Esse evento será executado antes do Form ser mostrado para o usuário. Entretanto, como queremos definir o carro como global, precisamos declará-lo fora do método. Então, logo acima da declaração do Form1_Load, declare e inicialize uma variável do tipo Carro. Agora, crie um método chamado ShowResults, que irá atualizar as labels lblportaesquerda, lblportadireita e lblvelocidade com os valores corretos. No evento Form1_Load, execute o método ShowResults. Volte agora para o modo de exibição. Clique em cada um dos botões, e implemente a lógica correspondente. Não se esqueça de chamar o método ShowResults, para atualizar os dados na tela para o usuário. Por fim, caso a velocidade caia abaixo de 0, ou passe do limite, mostre uma mensagem na tela para o usuário. A solução para este laboratório está contida no CD. Níveis de Acesso e Visibilidade Existem propriedades e métodos que, de alguma forma, devem ficar restritos à classe. Por exemplo, flags que mostram se a porta está trancada ou destrancada podem ficar ocultos ao exterior, e um usuário usaria uma função VerifTrancada() para saber se a porta está trancada (se a função retornar True) ou se ela está destrancada (se a função retornar False). Para isso, encapsula-se partes do conteúdo de forma a permitir que outras classes enxerguem propriedades e métodos. Fazemos isso através do controle dos níveis de acesso. 47

48 O nível de acesso de um elemento determina que código possui permissão para ler e executar o elemento. Código que não pode acessar um elemento, não pode acessar qualquer elemento contido dentro dele, mesmo que os elementos internos tenham um nível de permissão maior do que o elemento externo. Public O nível de acesso Public especifica que o elemento é acessível a partir de qualquer lugar dentro do mesmo projeto, de outros projetos que referenciam o projeto que o contém, ou de qualquer assembly construído a partir do projeto. Exemplo: public class Porta Private O nível de acesso Private especifica que os elementos somente são acessíveis dentro do mesmo contexto (módulo, classe ou estrutura) no qual foram declarados. Exemplo: private string cor; Protected Você só pode utilizar Protected em nível de Classe (dentro de uma). Protected especifica que o elemento é acessível apenas dentro da própria classe, ou por classes derivadas desta. public class Ambiente protected class Animal... protected class Leão : Animal... A classe derivada de uma outra classe deve possuir um nível de acesso menor ou igual à classe pai. 48

49 Internal O nível de acesso Internal especifica que os elementos serão acessíveis de dentro do mesmo Assembly, mas não fora dele. Um exemplo de declaração: internal string mensagem; Protected Internal É possível utilizar ambos os níveis de acesso Protected e Internal juntos em uma declaração para especificar que um elemento é acessível ou de classes derivadas, ou de dentro do mesmo assembly. protected internal string mensagem; Resumo dos Níveis Acesso Nível de acesso Elementos a que se aplica Contexto Public Qualquer código que pode visualizar um elemento público pode acessá-lo. Interfaces; Módulos; Classes; Estruturas; Propriedades; Atributos (internos); Constantes; Enums; Eventos; Declarações Externas; Delegates. Arquivo; Namespace; Interface; Módulo; Classe; Estrutura. Private Código dentro do mesmo contexto pode acessar. Interfaces; Módulos; Classes; Estruturas; Propriedades; Atributos (internos); Constantes; Enums; Eventos; Declarações Externas; Delegates. Módulo; Classe; Estrutura. Protected Código dentro da classe, ou de uma classe que herda desta podem acessar. Interfaces; Classes; Estruturas; Propriedades; Atributos (internos); Constantes; Enums; Eventos; Declarações Externas; Delegates. Classe. Internal Código dentro do mesmo assembly. Interfaces; Módulos; Classes; Estruturas; Propriedades; Atributos (internos); Constantes; Enums; Eventos; Declarações Externas; Delegates. Arquivo; Namespace; Interface; Módulo; Classe; Estrutura. Protected Internal Código dentro da mesma classe ou mesmo assembly, ou qualquer classe derivada da classe aonde o elemento está contido. Interfaces; Classes; Estruturas; Propriedades; Atributos (internos); Constantes; Enums; Eventos; Declarações Externas; Delegates. Classe. 49

50 Encapsulamento Existem atributos e métodos que, de alguma forma, devem ficar restritos à classe. Por exemplo, flags que mostram se a porta está trancada ou destrancada podem ficar ocultos ao exterior, e um usuário usaria uma função VerifTrancada() para saber se a porta está trancada (se a função retornar True) ou se ela está destrancada (se a função retornar False). Para isso, encapsula-se partes do conteúdo de forma a permitir que outras classes enxerguem propriedades e métodos. Fazemos isso, controlando os níveis de acesso. Notação UML A notação UML (de Unified Modeling Language) é um conjunto de diagramas que permitem que um analista especifique um sistema usando modelos-padrão adotados pelo mercado. Não é escopo deste curso explicar cada um dos diagramas e seus componentes (isso é tarefa para um curso de pelo menos 40 horas!), mas convém aqui mostrar como uma classe é mostrada em um diagrama de classes, que é comumente visto na literatura: Porta +cor : Integer -tipotrinco : String #fechada : Boolean #trancada : Boolean +Abrir() +Fechar() +Trancar() +Destrancar() +VerifTrancada() : Boolean Esse desenho corresponde à representação UML da classe abaixo: public class Porta public int cor; private string tipotrinco; protected bool fechada; protected bool trancada; public void Abrir() if (! trancada) fechada = false; 50

51 public void Fechar() if (! fechada) fechada = true; public void Trancar() if (fechada) trancada = true; public void Destrancar() trancada = false; public bool VerifTrancada() return trancada; Na notação UML, uma classe é representada por um retângulo dividido em três partes. Na parte superior, ficam o nome da classe. Na parte central, as propriedades, na parte inferior, as ações. Propriedades e métodos públicos são indicados com um sinal de (+) na frente do nome. Propriedades e métodos privados são representados com um sinal de (-) na frente do nome. Por fim, propriedades e métodos protected são representados com um sinal de (#). Herança O conceito de herança é largamente utilizado na orientação a objetos. Através desse conceito, uma classe pode herdar o que já é especificado em outra classe. Diz-se então que uma classe-filha está herdando de uma classe-pai ou uma superclasse. Vamos supor que estamos desenvolvendo um sistema para uma empresa que comercializa portas de todos os tipos e formas. Existem atributos e ações que são específicas de qualquer porta: - atributos: material, cor, tipo de fechadura, tipo de trinco, altura, largura, profundidade, peso, etc; 51

52 - ações: abrir, fechar, trancar, destrancar, etc. Essa classe atende à boa parte das portar que a empresa comercializa. Mas existem tipos de portas especiais que, além de terem as mesmas características da classe Porta, adicionam outras características novas. Mais ainda, existem portas que precisam de procedimentos modificados. Um exemplo é a porta de cofre. A porta de cofre, além de ter as características de uma porta tradicional, ainda precisa de um segredo para ser aberta junto com a chave e o trinco. Ao invés de reescrever uma classe PortaDeCofre inteira, o mais fácil é fazer com que essa classe herde todas as características de Porta, mas adicione algumas propriedades e que sobrescreva a implementação de Destrancar(), uma vez que essa porta em especial precisa tratar também do segredo do cofre. O diagrama UML ficaria assim: P o r t a + c o r : In te g e r - tip o T r in c o : S tr in g # fe c h a d a : B o o le a n # tr a n c a d a : B o o le a n + A b r ir ( ) + F e c h a r ( ) + T r a n c a r ( ) + D e s tr a n c a r ( ) + V e r ift r a n c a d a ( ) : B o o le a n P o r t a D e C o f r e - S e g r e d o + D e s tr a n c a r ( ) Dessa forma, ao criarmos uma instância de PortaDeCofre, se chamássemos PortaDeCofre.Abrir() ou PortaDeCofre.cor, não seria gerado erro: uma vez que PordaDeCofre herda de Porta, ao ser instanciado é criada uma área na memória com todo o conteúdo de porta e mais o conteúdo de PortaDeCrofre. 52

53 A implementação de herança no VB.NET é feita através da palavra-chave Inherits. O código que representaria uma porta de cofre ficaria então: public class PortaDeCofre : Porta É importante notar que, no.net, uma classe só pode herdar de 1 única classe (existem algumas linguagens de programação que permitem o que é chamado herança múltipla). Entretanto quando uma classe herda de outra, é como se ela herdasse também de todas as classes pai da classe pai dela. Ou seja, quando temos algo como: public class Animal public class Mamifero : Animal public class Leao : Mamífero A classe Leao acaba herdando da classe Animal indiretamente, na medida em que todo Leão é um Mamífero, e todo Mamífero é um Animal. Todas as classes, em algum nível, herdam do tipo Object, o tipo mais básico do CTS. Quando não declaramos uma classe pai para a nossa classe, o compilador automaticamente faz com que a nossa classe herde de Object. Classe Abstrata e Classe Selada Uma classe abstrata é uma classe que não pode ser instanciada ela é criada com o único propósito de servir de pai para outras classes. Ou seja, você não pode criar uma declaração usando New com uma classe do tipo abstrata. No C#, o modificador abstract implementa uma classe abstrata: public abstract class MinhaClasse Uma classe abstrata pode conter métodos abstratos ou não. Entretanto, uma classe não abstrata não pode conter métodos abstratos. Além do conceito de classe abstrata, existe também o conceito de classe selada. Uma classe selada é uma classe que não pode ser herdada ou seja, nenhuma classe pode derivar dela. O C# implementa classes seladas através do modificador NotInheritable: 53

54 public sealed class MinhaClasse Sobrescrita de Métodos Sobrescrevermos um método quando queremos substituir o método original por uma outra implementação, específica de uma classe filha. No C#, temos duas opções para sobrescrever um método: usando a palavra chave new, ou usando a palavra chave override. A diferença entre os dois métodos é que no primeiro caso, estamos criando um novo método com o mesmo nome e escondendo o membro original. Esse é o comportamento padrão, ou seja, não é necessário usar a palavra chave new, mas o compilador irá disparar um aviso, indicando a necessidade do new. Já no segundo caso, estamos estendendo a implementação para um membro herdado. Para que isso seja possível, na declaração original do método precisamos definir o método com um dos seguintes modificadores: abstract, virtual ou override (o modificador virtual define apenas que uma classe pode ser sobrescrita). No nosso exemplo da classe Porta, podemos sobrescrever o método Destrancar(), uma vez que PortaDeCofre só pode ser aberta se o segredo que o usuário inseriu for o correto. Nosso método, na classe PortaDeCofre, ficaria então: public override void Destrancar() if (segredo == "cges") base.destrancar(); Enquanto na classe Porta temos: public virtual void Destrancar() trancada = false; Note que usamos a instrução override para declarar que Destrancar() sobrescreve a implementação desse método. 54

55 Sobrecarga de Métodos Fazemos uma sobrecarga quando precisamos implementar um método que deve receber um conjunto diferente de parâmetros. No nosso exemplo, podemos escrever um método para abrir a porta, mas passando como parâmetro o segredo da porta. O usuário então teria outra opção para poder abrir a porta: ou ele atribui um valor à propriedade Segredo e chama Destrancar(), ou então ele chama Destrancar passando o segredo: public void Destrancar(string segredo) this.segredo = segredo; Destrancar(); Como é possível visualizar abaixo, quando você acessa um método que possui sobrecarga, é mostrado ao desenvolvedor uma lista, com todos as possíveis chamadas deste método. Acessando a classe pai base e this Há situações em que sobrescrevemos ou ocultamos membros da classe-pai. Como podemos indicar em nosso código se método que queremos usar é o membro original (da classe-pai) ou a especialização (da classe filha)? Quando estamos dentro de uma classe, o comando this permite indicar que usaremos o membro da classe em que estamos, e o comando base permite usar o membro a partir da classe-pai da qual estamos herdando. Polimorfismo Vamos agora voltar a falar um pouco mais sobre classes. 55

56 Quando falamos sobre sobrecarga de métodos, definimos uma classe filha da classe Porta a classe PortaDeCofre. Além disso, mostramos como era possível à classe filha sobrescrever um método da classe pai: Classe PortaDeCofre: public override void Destrancar() if (segredo == "cges") base.destrancar(); Classe Porta: public virtual void Destrancar() trancada = false; O que tudo isso de herança implica? Implica que a classe PortaDeCofre corresponde a um subgrupo do tipo Porta, e como tal possui características em comum com outras classes de porta (como PortaDeVidro). Quando estamos falando genericamente sobre Portas, uma PortaDeCofre pode ser usada como Porta. A esse conceito, dá-se o nome de Polimorfismo a capacidade de uma classe filha se passar por uma classe pai mesmo que, internamente, tenha mecanismos diferentes de funcionamento. Por exemplo, podemos declarar uma variável da seguinte forma: No exemplo acima, vemos como uma variável do tipo Porta pode receber uma variável do tipo PortaDeCofre. Entretanto, nesse momento todas as características 56

57 externas que diferenciam um PortaDeCofre de uma Porta ficam ocultas afinal, não estamos trabalhando com uma PortaDeCofre, mas com uma Porta! Entretanto, quando sobrescrevemos um método, a classe filha passa a ter um funcionamento diferente da classe pai. O que irá ocorrer nesse caso? Se pensarmos novamente na Porta e na PortaDeCofre, vemos que ambas funcionam de forma diferente. Como o funcionamento de uma Porta é diferente do funcionamento de uma PortaDeCofre, quando chamarmos o método Destrancar() estaremos chamando o método da classe especializada (PortaDeCofre), ao invés do método da classe pai. Apenas se a classe filha não tiver alterado a implementação, é que será chamado o método da classe pai. Lab: Trabalhando com Herança Vamos agora criar uma classe que represente um carro esportivo. Um carro esportivo corre muito mais rápido que um carro normal, mas ainda tem 2 portas. Abra a solução WindowsApplicationCS, desenvolvida anteriormente. Adicione uma nova classe CarroEsportivo. Essa nova classe deve herdar da classe Carro. Na classe Carro, transforme a propriedade velocidade de private para protected, de forma que seja possível alterar o seu valor a partir da classe filha. Sobrescreva o método Acelera, para permitir ao condutor acelerar até 250 Km/hora, e substitua a chamada para a classe Carro, por uma chamada à classe CarroEsportivo. Rode a sua aplicação e verifique o que acontece quando você acelera seu carro acima de 180 km/hora. Para ver a resposta do exercício, abra o Lab Trabalhando com Herança, do CD. Interface Interfaces, como classes, definem um pacote de propriedades e métodos. Entretanto, diferentemente de classes, interfaces não provêm implementação. Uma interface funciona como um contrato, no qual a classe que a implementa precisa implementar todos os aspectos definidos pela interface exatamente como definida. 57

58 A grande vantagem de interfaces, é que apesar de uma classe só poder herdar de uma única classe, ela pode implementar inúmeras interfaces diferentes. public interface IPessoa public string GetNome(); public class PessoaFisica : IPessoa private string nome; public string GetNome() return nome;... Métodos, Atributos e Propriedades Estáticas Uma propriedade, um atributo ou um método estático podem ser vistos como uma característica da classe e não do objeto. O que isso significa? Lembra-se de quando falamos que, quando declaramos um objeto usando a palavra-chave New, estamos alocando um espaço na memória onde os dados do objeto ficarão alocados? Um atributo estático não fica armazenado nesse espaço, mas sim fica armazenado junto com a definição da classe. Isso significa que, todos os objetos criados a partir da classe irão acessar o mesmo dado. Vamos considerar, como exemplo, a classe ContadorAcessos abaixo: public class ContadorAcessos public int conta = 0; public void SomaUm() conta++; public int Total() return conta; Vamos agora utiliza a nossa classe: 58

59 ContadorAcessos contador1 = New ContadorAcessos(); ContadorAcessos contador2 = New ContadorAcessos(); contador1.somaum(); contador1.somaum(); contador2.somaum(); MessageBox.Show( contador2.total().tostring() ); Qual será o resultado? 1. Agora, se modificarmos um pouco a nossa classe: public class ContadorAcessos public static int conta = 0; public void SomaUm() conta++; public int Total() return conta; O que teremos como resultado? 3. Além disso, outra propriedade de atributos, métodos e propriedades estáticas é que não é necessário declarar uma instância da classe para podermos acessá-los. Podemos acessá-los diretamente a partir do nome da classe, como em: Como exemplo de um método estático no.net, podemos citar o já mostrado método Show(), da classe MessageBox. Classes Parciais O C# permite que uma classe seja declarada ao longo de vários arquivos. Isso é vantajoso em trabalho em equipe, já que programadores podem trabalhar em fragmentos da classe em arquivos separados. Quando o compilador for chamado, ele mesmo se encarregará de juntar as partes de uma classe e produzir uma classe apenas. 59

60 A classe original deve ser implementada normalmente. Entretando, durante a declaração da classe parcial, basta declará-la adicionando a palavra chave Partial: public partial class... Revisão Vimos neste capítulo um pouco sobre os conceitos de programação orientada a objetos, e como esses conceitos são implementados na prática no C#. Nos capítulos seguintes, trataremos de conceitos mais avançados de programação. 60

61 Capítulo 6 Tópicos Avançados Objetivos O objetivo deste capítulo é introduzir ao leitor tópicos mais avançados de programação no Visual C# 2.0. Falaremos sobre como classes são agrupadas em namespaces e sobre como fazemos quando precisamos acessar classes contidas em outros projetos. Ainda neste capítulo, falaremos sobre as bibliotecas que já vem junto com o framework, e encapsulam funções rotineiras. Por fim, completamos falando sobre tratamento de erros no.net. Namespaces Para melhor organizar o conteúdo, as classes podem ser agrupadas em namespaces. Namespaces são unidades lógicas de códigos que agregam classes que possuem um assunto em comum (que podem ser agrupadas juntas). Os namespaces podem ser mais bem entendidos, se o compararmos a caminhos de diretórios. Quando queremos, em uma máquina Windows, acessar o Notepad.exe, o caminho que usamos é: c:\windows\notepad.exe. Analogamente, se precisamos acessar uma classe que copia um arquivo, usamos: System.IO.File.Copy(). O caminho aqui demonstrado é lido da seguinte forma: a classe Copy(), que está dentro do namespace System, dentro de IO e dentro de File. É bom diferenciarmos aqui um namespace de um assembly. Quando compilamos um projeto, todo o código fonte daquele projeto é compilado e transformado em 1 único arquivo (que pode ser um.exe ou um.dll, dependendo do tipo do projeto), ou assembly. Em geral, um projeto possui um namespace único e distinto. Entretanto, um namespace não obrigatoriamente deve estar restrito a um único assembly. Podemos ter mais duas classes diferentes, em dois projetos diferentes, que pertençam a um único namespace. Além disso, em um mesmo projeto podemos ter a definição de classes de namespaces distintos. 61

62 As produtoras de software costumam usar essa notação para criar seus próprios namespaces. São exemplos: empresa.utils, empresa.sistema1.calculo, e assim por diante. Aqui surgem algumas dúvidas. A primeira delas se refere a como fazemos com que a nossa classe pertença a um namespace? Por default, todas as classes que pertencem a um projeto pertencem a um mesmo namespace, que você pode definir clicando em My Project, na tab Application. O namespace raiz do seu projeto fica definido em Root Namespace (alguns tipos de projetos não possuem essa opção como projetos do Office). Por default, esse namespace possui o mesmo nome do projeto. Existem 2 modos de alterar o namespace de uma classe. A primeira, delas é alterar o conteúdo do Root Namespace. Isso fará com que todas as classes de seu projeto que forem criadas a partir de agora passem a usar este como namespace. Entretanto, podemos querer especificar o namespace no nível da classe. Além disso, quando alteramos o valor aqui não estamos alterando o valor das classes já criadas. Como fazer isso? Através do comando Namespace. 62

63 namespace WindowsApplicationCS.Carros public class Carro... No exemplo acima, definimos que a classe Carro pertence ao namespace WindowsApplicationCS.Carros. Essa classe agora só estará automaticamente visível para as classes que pertençam ao mesmo projeto e ao mesmo namespace. E agora, como fazemos para que as outras classes enxerguem essa classe? Fazemos isso adicionando o namespace à lista de namespaces referenciados, usando o comando using: Com isso, a partir de agora essa classe possui acesso aos elementos desse namespace. Outro uso para Using Além da forma indicada acima, existe outro modo de utilizar o comando Using. Poderíamos utilizar o comando: using Car = WindowsApplicationCS.Carros; Para declarar que, a partir de agora, quando nos referirmos a Car, estamos apontando para o namespace WindowsApplicationCS.Carros. O impacto disso é que, a partir deste momento, as referências: Car.Carro carro = new Car.Carro(); WindowsApplicationCS.Carros.Carro carro = new WindowsApplicationCS.Carros.Carro(); São idênticas! 63

64 Referências Vimos, na sessão anterior, como fazemos para referenciar uma classe que está em um outro namespace. E se a classe não estiver apenas em um outro namespace, mas sim em outro projeto, ou em uma biblioteca externa (como as bibliotecas do.net)? Para fazer com que o seu projeto tenha uma referência para outro, clique com o botão direito em cima do objeto References contido no projeto e selecione Add Reference.... Nessa tela, você verá a lista de referências guardadas pelo seu projeto. Quando você clica no botão Add..., é aberta a janela Add Reference. Aonde você tem as seguintes tabs:.net Aqui você tem acesso a todas as bibliotecas do.net, além de bibliotecas de componentes registradas por terceiros no respositório de bibliotecas do.net (também chamado Global Assembly Cache ou GAC); 64

65 COM Nesta tab, você tem acesso aos componentes registrados no COM+. Quando você adiciona uma referência a uma biblioteca do COM+, o Visual Studio automaticamente gera código que encapsula o acesso ao componente, para que seja transparente para o desenvolvedor esse acesso; Projects Aqui, você pode dizer que um projeto aponta para outro contido na mesma solução. Isso significa que o projeto que referencia outro é sempre compilado depois, e quando o projeto referenciado é compilado, o Visual Studio faz uma cópia do assembly gerado para a pasta de recursos do projeto; Browse Nesta janela você pode procurar uma biblioteca. É utilizada quando você vai referenciar componentes que não foram registrados nem no GAC, nem no COM+, e também não fazem parte da sua solução; Recent Contém uma lista dos projetos mais recentemente adicionados a qualquer projeto. Todas as opções mostram listas de componentes. Basta selecionar um componente da lista desejada, e clicar em OK. A partir de agora, o projeto já referencia a biblioteca. Lab: Trabalhando com Namespace e Referências Vamos agora verificar como trabalhar com namespaces e referências. Para ilustrar o desenvolvimento, vamos extrair as classes Porta, Carro e CarroEsportivo do projeto WindowsApplicationCS, criar um projeto do tipo biblioteca de classes, colar as classes nessa biblioteca, e fazer o nosso projeto apontar para essa biblioteca. Abra a solução WindowsApplicationCS. Clique com o botão direito em cima do nome da solução, e selecione Add > New Project. 65

66 Selecione o projeto Class Library, e dê o nome de ClassesDeNegocio. Deixe que o projeto fique na mesma estrutura da solução, e clique em OK. Verifique que um novo projeto foi adicionado à sua solução: Agora, clique com o botão direito na Class1.cs e remova a mesma da aplicação. Arraste as suas 3 classes (Carro, CarroEsportivo e Porta) para o novo projeto, e remova-os da classe original. Abra cada uma das classes e altere o Namespace para ClassesDeNegocio. Tente compilar novamente a sua solução. Você receberá a seguinte mensagem de erro: 66

67 Esse erro ocorre porque o seu projeto WindowsApplicationCS não sabe aonde encontrar a classe CarroEsportivo. Vamos agora resolver o problemas, adicionando a referência correta. Clique com o botão direito em References do projeto WindowsApplicationCS, e selecione Add Reference. Na janela que se abre, selecione a tab Projects, e o projeto ClassesDeNegocio. Compile sua aplicação e veja o resultado. Engraçado, agora que eu apontei para a biblioteca correta deveria ter funcionado, não é? A resposta é não. Eu disse apenas para o.net incluir a biblioteca quando for compilar o projeto, mas eu não disse para a minha classe para buscar dentro do namespace dessa classe as bibliotecas que forem necessárias. No seu form, adicione o seguinte Namespace: using ClassesDeNegocio; Rode agora o seu projeto e você verá que a compilação funcionou. Teste a aplicação, para garantir que ela faça tudo exatamente como fazia antes. O resultado desse lab está contido no CD em anexo. Bibliotecas do Framework.NET 2.0 Quando falamos sobre o Framework.NET, dissemos que existe uma Base Class Library (BCL) que já vem com diversas classes prontas para serem utilizadas no.net, que desempenham rotinas comumente utilizadas, e que podem ser utilizadas independentemente da linguagem que estivermos utilizando, desde que esta se baseie sobre o Framework. Nesta seção falaremos um pouco sobre as bibliotecas mais utilizadas. O namespace System O namespace System é ande reside a maior parte do Framework.NET. Ele está contido em System.dll no GAC. Entretanto, o Visual Studio já adiciona a referência a esta biblioteca automaticamente, independente do projeto. Na raiz de System estão os tipos básicos do.net, como System.String, System.Integer, System.Double. 67

68 Nota Embora String, Integer, Double, Single e outros tipos numéricos sejam primordialmente vistos como simples variáveis, o.net pode enxergá-los também como objetos. Para que uma simples soma de dois inteiros não seja uma tarefa de uso intensivo de recursos, o.net se vale de uma técnica chamada boxing e unboxing. Sempre que criamos uma variável, a ela é atribuído um valor e suas operações são feitas em pilha. Dizemos então que usamos um tipo valor. Se desejarmos usar algum recurso o objeto System.Int32, o.net então realiza o boxing e passa a tratar a variável como um tipo referência. Caso voltemos a fazer operações simples, o.net realiza o unboxing, e a variável passa a ser um tipo valor. Em System também estão classes que agregam métodos de uma funcionalidade específica. A classe System.Math, por exemplo, contém métodos matemáticos, como Sin, Cos, Round. A classe System.Console contém métodos para entrada/saída na console como WriteLine e ReadLine. O namespace System.Text No namespace System.Text estão agrupadas as classes específicas para tratamento de textos. Esse namespace também está contido dentro da bibliote System.dll. A classe mais usada é a StringBuilder, que fornece uma maneira muito mais eficiente de fazer concatenação de várias strings. Dentro de System.Text há um outro namespace, de grande importância para programadores: o System.Text.RegularExpressions, que permite pesquisa, troca e quebra de strings segundo critérios de expressões regulares. O namespace System.Collections O namespace System.Collections contém classes prontas para tratamento de estruturas de dados. Esse namespace também está contido dentro da bibliote System.dll. Essas estruturas contém métodos prontos para adição, remoção e busca interna e são ferramentas essenciais para programadores. São elas: Stack (pilha), com funcionalidade LIFO (último a entrar, primeiro a sair); 68

69 Queue (file), com funcionalidade FIFO (primeiro a entrar, primeiro a sair); ArrayList, um array com métodos de inserir/apagar itens em operações simples. Seus itens são acessados com índices, de modo similar a um array. A sua grande vantagem é a flexibilidade quando não se sabe a quantidade de elementos ou quando essa quantidade varia muito, tornando o ReDim usual, o que é custoso em termos de desempenho da aplicação; HashTable, que permite o uso de dados do tipo chave=valor, de modo similar ao que encontramos em arquivos INI. Seus itens são acessados através de chave. Esta estrutura de dados é comum e necessária em muitas aplicações e a sua funcionalidade vai adiantar muitas horas de programação e correção de bugs; SortedList, que reúne as características de um ArrayList e um HashTable. Seus itens são ordenados de acordo com a chave e podem ser acessados através do índice ou de sua chave. Trabalhando com HashTables Conforme falado, a HashTable é uma estrutura para tratar dados do tipo chave=valor, assim como podia ser visto em arquivos INI. O exemplo abaixo demonstra uma classe com um método que preenche uma HashTable (Preenche) e outra que realiza uma busca por uma chave (ObtemValor), retornando uma string vazia se não for encontrada ou então o valor relacionado se a chave não existir. public class DemoHashTable Hashtable hs = new Hashtable(); public DemoHashTable() Preenche(); private void Preenche() hs.add("nome", "José"); hs.add("sobrenome", "da Silva"); hs.add("endereço", "Rua das Árvores, 14"); hs.add("cidade", "Fernandópolis"); public string ObtemValor(string chave) 69

70 string str = ""; if (hs.contains(chave)) str = hs[chave].tostring(); return str; O namespace System.IO O namespace System.IO é aonde residem as funções de entrada/saída usadas em arquivos, em impressoras, em streaming e em aplicações derivadas. Posteriormente teremos uma seção dedicada ao I/O de arquivos em que usaremos parte das classes desse namespace. Esse namespace também está contido dentro da bibliote System.dll. Escrevendo um arquivo FileStream fs = new FileStream(@"c:\texto.txt", FileMode.Create); StreamWriter sw = new StreamWriter(fs); sw.writeline("a raposa "); sw.writeline("correu do caçador"); sw.close(); Lendo um arquivo StreamReader sr = new StreamReader(@"c:\texto.txt"); StringBuilder sb = new StringBuilder(); while (!sr.endofstream) sb.appendline(sr.readline()); System.Console.WriteLine(sb); Tarefas recorrentes Usualmente temos que fazer algumas tarefas que são praxe do dia-a-dia de um desenvolvedor. Aqui estão algumas: Acessando o diretório da aplicação string AppDir = System.IO.Path.GetDirectoryName (System.Reflection.Assembly.GetExecutingAssembly().Location); Verificando o nome do computador Nome NetBIOS: string NomeComp = System.Environment.MachineName; 70

71 Nome DNS: string ndns = System.Net.Dns.GetHostByName("LocalHost").HostName; Verificando a versão do sistema operacional string osver = System.Environment.OSVersion; Verificando o usuário que está rodando o programa string usr = System.Environment.UserName; Tratamento de Erros Uso de Try/Catch/Finally O uso de Try/Catch é ferramenta já conhecida de programadores Delphi. O Try/Catch é uma ferramenta útil e de uso recorrente. Tratamento estruturado de erros try/catch Objetos que encontram algum problema durante a sua execução geram exceções que notificam ao objeto que os chamou algo sobre o problema de funcionamento. Exceções são objetos da classe System.Exception ou derivadas dela. Um exemplo para melhor ilustrar: quando temos um vetor com 10 elementos e tentamos acessar o 11º, é gerado um exception do tipo IndexOutOfRangeException, que herda de System.SystemException. Normalmente cada tipo de erro tem uma exception correspondente. Caso um erro não tenha uma exception correspondente, pode ser usada a classe System.Exception genérica. Os tipos mais comuns de exceção são: System.Exception Corresponde a uma exceção genérica; System.ApplicationException Uma exceção que ocorreu na aplicação; System.ArgumentException Quando um dos parâmetros que passamos para um método é de um tipo inválido; 71

72 System.ArgumentNullException Disparada quando um dos parâmetros que você passou para um método continha null, e esse método não suporta esse valor; System.ArgumentOutOfRangeException Disparada quando um dos valores passados a um método estoura a capacidade do método; System.ArithmeticException Disparada quando ocorrem erros aritméticos e de conversão; System.InvalidCastException Disparada quando ocorre um erro de conversão; System.Data.SqlClient.SqlException Disparada quando ocorre uma exceção em uma conexão a um banco SQL, utilizando o SqlClient; System.Data.OleDb.OleDbException Similar à versão do SqlClient, disparado quando ocorre uma exceção em uma conexão via OleDb; System.IO.IOException Exceção genérica de I/O para disco, disparada sempre que ocorre um erro de IO. System.IO.FileNotFoundException Disparada quando um arquivo que você está tentando acessar não existe (herda da IOException); O tratamento de erros com exception é feito isolando-se partes do código com try/catch. A instrução try marca o começo do bloco aonde, se for recebida uma exceção, ela será tratada pelo bloco catch. Dessa forma, aproveitando o exemplo do IndexOutOfRangeException, definiremos um método aonde o exception aparece e, quando disparado, escreve índice fora do limite no console: public void TesteDeException() int[] vetor = new int[3]; try for (int i = 0; i <= 4; i++) vetor[i] = i; catch (exception e) 72

73 System.Console.WriteLine("índice fora do limite"); Exceptions são verificadas na ordem em que foram declaradas, assim como o seria em uma instrução Switch..Case. Se dentro de um try puderem ocorrer vários exceptions, eles podem ser tratados independentemente: public void TesteDeException() int[] vetor = new int[3]; try for (int i = 0; i <= 4; i++) vetor[i] = i; catch (ArgumentException e) System.Console.WriteLine("problemas no argumento"); catch (IndexOutOfRangeException e) System.Console.WriteLine("índice fora do limite"); catch (Exception e) System.Console.WriteLine(ex.Message); No nosso exemplo, há tratamento para três tipos de exceções: duas são específicas (ArgumentException e IndexOutOfRangeException) e outra genérica (Exception). A primeira exceção a ser testada é ArgumentException, que é disparada quando os argumentos de uma chamada de método estão com alguma incompatibilidade com a declaração. A segunda exceção a ser testada é IndexOutOfRangeException. Como essa é a exceção que nós sabemos que será disparada, a linha que escreve índice fora do limite é executada e o fluxo segue para o final do try. A terceira exceção é testada apenas quando as outras não coincidiram com a exceção que foi disparada. Note que, ao usar a classe Exception, estamos fazendo algo como um switch default de um switch...case. Note também que temos acesso à mensagem do Exception, através da propriedade Message. 73

74 Exceções personalizadas Caso você esteja desenvolvendo código e deseje criar exceptions próprias, basta criar uma classe que herda de Exception, como no exemplo abaixo: public class MinhaException :Exception public override string Message get return "Ocorreu uma MinhaException"; Note que neste código, a propriedade Message foi sobrescrita, de forma a retornar uma string por nós definida. Disparando exceptions Para disparar exceptions, usamos o comando throw. Nunca se esquecendo que um Exception nada mais é que um objeto, usamos o comando abaixo para disparar uma Exception genérica: public void Abre() if (trancada) throw new Exception("A porta está trancada"); Finally Ao blocos try...catch, é possível usar finally, que é executado sempre, tenha havido uma exception ou não. Uma utilidade importante dessa instrução é, por exemplo, fechar um arquivo se houver uma exception de I/O ou fechar uma conexão com o banco de dados. public void TesteDeException() int[] vetor = new int[3]; try for (int i = 0; i <= 4; i++) vetor[i] = i; catch (Exception e) System.Console.WriteLine(ex.Message); 74

75 finally Console.WriteLine("Ocorrendo ou não uma exception, você verá essa mensagem"); Revisão Neste capítulo, vimos o que é um namespace, aprendemos a acessar classes contidas em outros projetos ou bibliotecas, falamos um pouco sobre algumas das bibliotecas contidas no Base Class Library do framework.net, falamos sobre tarefas recorrentes e, por fim, falamos sobre o conceito de tratamento de erros do.net. Nos próximos capítulos, iremos nos aprofundar mais no.net. 75

76 Capítulo 7 XML Objetivos No mundo conectado de hoje, ser capaz de falar um protocolo comum com clientes, parceiros e fornecedores torna-se cada vez mais importante. O protocolo escolhido hoje em dia para isso é o XML. Esse capítulo servirá como uma introdução ao formato XML. O objetivo deste capítulo é explicar rapidamente o que é o XML, quais são as diferenças entre XML e HTML, e mostrar como utilizar o XML em suas aplicações. O que é XML? A sigla XML vem de Extensible Markup Language, e é uma recomendação do W3C, como linguagem padrão para a descrição de dados na Web. A sua função é definir um formato comum para a troca de informações entre diferentes sistemas. O XML nada mais é que um arquivo texto (com extensão.xml), baseado em tags, de forma semelhante ao HTML. Entretanto, diferente do HTML, a sua função é estruturar, armazenar e transportar dados não como exibi-los. E, para tanto, as suas tags não são previamente definidas as tags são definidas pelo autor. Vejamos um exemplo: Vemos, nesse exemplo, como seria um XML que representa um pedido de um cliente. Enteremos o funcionamento desse exemplo nas sessões seguintes. 76

77 Elementos de um Documento XML Um documento XML, como o mostrado no exemplo, é composto dos seguintes elementos: Declaração A primeira linha que compõe um documento XML é a declaração: <?xml version= 1.0 encoding= utf-8?> O atributo version define a versão do XML que estaremos trabalhando. O atributo encoding define a codificação dos caracteres que utilizamos quando da criação do documento. Assim, em nossa declaração definimos que o documento foi feito utilizando-se da codificação UTF-8. Tags No XML, uma tag (ou elemento) corresponde a um campo. Assim, quando definimos: <Pedido> <IdUsuario>153</IdUsuario> <DataFaturamento> </DataFaturamento> <Itens> <Item id= 1 > <IdItem>5</IdItem> <Quantidade>1</Quantidade> </Item> <Item id= 2 > <IdItem>2</IdItem> <Quantidade>5</Quantidade> </Item> </Itens> </Pedido> Definimos que um Pedido possui um IdUsuario, DataFaturamento, e uma coleção de Itens, onde cada Item dessa coleção é definido como tendo um IdItem e uma Quantidade. Um documento XML deve possuir a seguinte estrutura: <root> <child> <subchild>...</subchild> </child> </root> 77

78 Uma tag (ou elemento) pode ter diversos tipos de conteúdos diferentes, e inclui tudo entre o inicio de uma tag, até o final da tag de fechamento. Assim, ela pode conter texto, outras tags e atributos. Deve-se notar que no XML: Todas as tags precisam ter uma tag de fechamento; As tags são case-sentitive ou seja, <Pedido> é diferente de <pedido>; As tags XML devem vir na ordem correta Não é válido algo do gênero: <Item><IdItem>5</Item></IdItem>; Todos os documentos XML devem ter uma tag inicial (que define o objeto que é descrito pelo documento), e essa tag deve ser única a chamada root. A nomenclatura das tags no XML deve seguir as seguintes regras: Podem conter letras, números e outros caracteres; Não devem começar com números ou caracteres de pontuação; Não podem começar com xml (ou Xml, XML, etc); Não podem conter espaços. Entretanto, como os dados de um arquivo XML geralmente mapeiam dados de um banco, ou outra fonte de dados, como boas práticas adotam-se em geral algumas outras restrições recomendadas: Use nomes descritivos, mas não exagere no tamanho; Evite usar símbolos matemáticos (=, -, +, /, :); Caracteres específicos de língua são válidos entretanto, isso pode causar problemas quando outra empresa for consumir os seus dados. Desta forma, evite-os; 78

79 Atributos No XML, uma tag pode possuir um ou mais atributos. Atributos, em geral, carregam informação que não é parte do dado, mas que é importante para o programa que está manipulando os dados entender do que se trata. <Item id= 1 > No exemplo acima, dissemos ao programa que irá tratar o XML que esse é o primeiro item da lista de itens do usuário. Atributos precisam sempre ser definidos entre ou. Se internamente ao elemento já houver ou, é necessário utilizar a outra opção na definição. Apesar dos atributos poderem conter dados, assim como as tags, elas possuem diversas desvantagens quanto a estas: Atributos não podem conter múltiplos filhos (como uma tag pode); É mais complexo adicionar um novo atributo do que uma nova tag; A validação dos dados do documento é mais complexa contra atributos; Eles tornam mais difícil a leitura e manutenção de um documento. Comentários Como no HTML, no XML os comentários são feitos utilizando-se <! > : <!-- Este é um comentário! --> XML Bem Formado Diz-se que um XML é bem formado, quando ele atende as regras de sintax do XML, que foram descritas anteriormente. Definindo a Estrutura do Documento Dissemos que o XML foi desenvolvido para que fosse possível a intercomunicação entre diferentes sistemas pela internet. Também dissemos que o formato do documento XML é definido pelo usuário. Assim sendo, como fazemos com que um sistema reconheça o formato do documento que estamos enviando? Além disso, como verificamos que um documento atende aos requisitos corretos (por exemplo, o campo DataFaturamento contém uma data válida)? 79

80 Fazemos isso através da criação de um documento que define a estrutura do nosso XML. Existem duas formas de fazer essa definição: através de DTD, ou usando Schemas. O DTD foi a primeira definição de um formato de documento; entretanto, os XML Schemas estão substituindo esse formato, e vem se tornando o padrão. Não é o objetivo deste curso entrar em detalhes na criação de um DTD ou de um XML Schema, mas mais informações podem ser encontradas na bibliografia indicada no final da apostila. Imaginando um XML do tipo: <Pedido> <IdUsuario>12</IdUsuario> <DataFaturamento> </DataFaturamento> <Itens> <Item id= 1 > <IdProduto>5</IdProduto> <QtdProduto>1</QtdProduto> </Item> <Item id= 2 > <IdProduto>123</IdProduto> <QtdProduto>10</QtdProduto> </Item> </Itens> </Pedido> Um exemplo de DTD: <?xml version="1.0"?> <!DOCTYPE Pedido [ <!ELEMENT Pedido (IdUsuario,DataFaturamento,Itens)> <!ELEMENT IdUsuario (#PCDATA)> <!ELEMENT DataFaturamento (#PCDATA)> <!ELEMENT Itens (Item*)> <!ELEMENT Item (IdProduto,QtdProduto)> <!ELEMENT IdProduto (#PCDATA)> <!ELEMENT QtdProduto (#PCDATA)> <!ATTLIST Item id CDATA 0 > ]> Um exemplo de Schema: <?xml version="1.0"?> <xs:schema xmlns:xs=" targetnamespace=" " xmlns=" " elementformdefault="qualified"> <xs:element name="pedido"> <xs:complextype> <xs:sequence> 80

81 Revisão <xs:element name="to" type="xs:string"/> <xs:element name="from" type="xs:string"/> <xs:element name="heading" type="xs:string"/> <xs:element name="body" type="xs:string"/> </xs:sequence> </xs:complextype> </xs:element> </xs:schema> Além da definição da estrutura, você precisa de um parser, ou seja, um programa que seja capaz de validadar a estrutura do XML e confirmar a sua validade. Os browsers mais modernos já possuem parsers embutidos, e o.net, através da biblioteca System.Xml, possui classes e métodos que permitem trabalhar com os documentos XML, e realizar a sua validação. Nesse capítulo, vimos o que é um documento XML, como este é formado e como fazemos a validação da estrutura do documento e dos dados contidos nele. 81

82 Capítulo 8 ADO.NET Objetivos Neste capítulo, vamos estudar o funcionamento do ADO.NET, o novo pacote de classes que expõe serviços de acesso a dados para a programação.net. Iremos ver quais são os classes do ADO.NET que permitem abrir uma conexão, executar comandos, e recuperar dados do banco incluindo o estudo do importante objeto DataSet, que permite trabalhar de forma desconectada com uma cópia dos dados na memória, e como fazer para utilizá-lo para recuperar dados de um arquivo XML. O que é o ADO.NET O ADO.NET é um pacote de classes que expõe serviços de acesso a dados para a programação.net. Ele veio para substituir o RDO, o DAO, e por fim o ADO. Além de ser totalmente aderente ao.net, ele traz vantagens consideráveis, tais como: Acesso desconectado a dados; Provedores de acesso dedicados a fornecedores de bancos de dados; Dataset que permite agregar várias tabelas e apontar relacionamentos; Manipulação direta de XML; Possibilidade de popular dados a partir de arquivos XML, objetos, etc. Providers do.net O.NET possui provedores especializados para bases de dados de diferentes fornecedores. A maior vantagem de se usar provedores especializados é que eles são escritos de forma a aproveitar o melhor que o sistema gerenciador de banco de dados oferece. Os provedores que estão disponíveis por default são: Data Provider for SQL Server (System.Data.SqlClient); 82

83 Data Provider for OLEDB (System.Data.OleDb); Data Provider for ODBC (System.Data.Odbc); Data Provider for Oracle (System.Data.OracleClient). É possível acessar bancos de dados usando os provedores ODBC e OLEDB, mas os provedores especializados oferecem acesso otimizado e mais rápido, além de acesso à características específicas de cada banco. Modelo ADO.NET DataAdapte r DataSet WindowsFor m WebForm Connection Command Classes DataReader WebServices Provider ADO.NET Consumidores Connection O objeto Connection é encontrado dentro do provider. Os objetos default do.net são SqlConnection, OracleConnection, OleDbConnection, OdbcConnection. Além da especificidade da base de dados a ser acessada, a classe Connection provê métodos e propriedades similares aos encontrados no objeto Connection antigo. As strings de conexão antigas também são similares às usadas no.net. Command O objeto Command, já velho conhecido do ADO, recebeu novas funcionalidades no ADO.NET. Do Command é a responsabilidade de receber instruções SQL (e chamadas de Stored Procedures). 83

84 O Command faz parte do conjunto de componentes que um Provider oferece, e existe um Command para cada provedor: SqlCommand, OracleCommand, OleDbCommand, OdbcCommand. Assim como no ADO, o Command do ADO.NET tem uma coleção de parâmetros (Parameters) que são passados para instruções SQL. O Command possui quatro métodos que são usados com freqüência: ExecuteReader: retorna um DataReader, objeto usado para leitura rápida da base de dados. O DataReader será assunto do próximo tópico; ExecuteNonQuery: usado quando o comando SQL não retornará nenhum tipo de dado (como instruções INSERT, por exemplo); ExecuteScalar: quando o comando SQL retorna um único valor (como um select count(*), por exemplo); ExecuteXMLReader: idem ao ExecuteReader, retorna um XMLReader. DataReader O DataReader é um objeto de leitura de dados, rápido e eficente, que funciona como um antigo Recordset marcado com a opção adopenforwardonly: ele promove escrita somente adiante, sem possibilidade de navegar registros para trás, e tembém read-only. A grande vantagem do DataReader é a sua velocidade: ele deve ser usado quando for necessário ler grandes quantidades de dados que não serão modificados como, por exemplo, em relatórios ou listagens. O DataReader é específico de cada provedor: SqlDataReader, OracleDataReader, OleDbDataReader, OdbcDataReader. O DataReader é uma classe estática e nunca deve ser instanciado. Ele deve sempre receber a referência de um outro objeto que retorne um DataReader, como por exemplo um objeto Command, como veremos no exemplo abaixo. Para usar o DataReader, criaremos um objeto Connection que acessa a base NorthWind, inseriremos o comando de consulta (instrução SQL) e chamaremos o 84

85 método ExcecuteReader. A leitura é feita em um loop que chama o método Read(), como demonstrado abaixo: StringBuilder sb = new StringBuilder(); SqlConnection cn = new SqlConnection(); cn.connectionstring = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=c:\\somepath\\mydb.mdb; " + "User Id=admin; Password=MyPass;"; SqlCommand cmd = new SqlCommand(); cmd.connection = cn; cmd.commandtext = "select * from customers"; cn.open(); SqlDataReader dr; dr = cmd.executereader(); while (dr.read()) sb.append(dr["companyname"]); sb.append(";"); dr.close(); cn.close(); Note que não fazemos mais a verificação de EOF e nem precisamos nos preocupar com MoveNext. Ao chamarmos Read() ele já move o cursor um registro à frente e retorna True, ou retorna False se não houver mais registros a serem lidos. DataAdapter O DataAdapter é um objeto especializado em intermediar as requisições de acesso a dados da aplicação e o banco de dados. A idéia do DataAdapter é prover a parte funcional do acesso aos dados, agreagando dentro de si objetos do tipo Command (um para select, um para update, um para insert e outro para delete). Do DataAdapter é a responsabilidade de preencher (ou popular) um Dataset, e também receber do DataSet modificações e executá-las no banco de dados. Cada provedor tem um DataReader específico. São eles: SqlDataAdapter, OracleDataAdapter, OleDbDataAdapter e OdbcDataAdapter. Através do método Fill do DataAdapter, preenchemos DataTables de DataSets, conforme será mostrado e exemplificado no próximo tópico. 85

86 Criando comandos automaticamente: o CommandBuilder A classe CommandBuilder permite que sejam criados objetos Command para atualizar (update), inserir (insert) ou apagar (delete) registros de um dataset. A grande vantagem de usar o CommandBuilder é que não é necessário especificar a lista de campos a serem alterados nem especificar um objeto Parameter para cada um deles. O CommandBuilder pode ser usado apenas quando usamos um SelectCommand simples, que usa um comando SELECT em uma tabela (e não uma stored procedure ou select em uma view) e que não use cláusulas mais complexas, como JOIN. Ao ser chamado, o CommandBuilder: 1. conecta na base de dados e obtém o esquema da tabela; 2. prepara os comandos correspondentes, usando a lista de campos obtida; 3. instancia objetos Parameter, de acordo com o tipo de cada campo. O CommandBuilder faz parte das classes especificas de cada provider, por isso há um command builder para cada provider. O exemplo abaixo ilustra como criar um objeto CommandBuilder e fazer com que ele crie automaticamente os comandos de update, insert e delete. A classe recebe como parâmetro um DataSet que sofreu atualizações, replicando-as para o banco de dados. O procedimento abaixo também espera que o DataSet contenha uma tabela Clientes que foi populada com o comando SQL select * from Customers: public void Atualiza(DataSet ds) SqlConnection cn = new SqlConnection("Data Source=TOMAC;Initial" + "Catalog=Northwind;Integrated Security=True"); SqlCommand cmd = new SqlCommand("select * from Customers", cn); SqlDataAdapter da = new SqlDataAdapter(cmd); SqlCommandBuilder cb = new SqlCommandBuilder(da); da.updatecommand = cb.getupdatecommand(); da.insertcommand = cb.getinsertcommand(); 86

87 da.deletecommand = cb.getdeletecommand(); da.update(ds.tables["clientes"]); cn.close(); DataSet O DataSet é um objeto genérico do ADO.NET, independente de qual provedor está sendo usado para acesso aos dados. Sua função é gerenciar dados previamente adquiridos por acesso a bancos de dados, acesso a arquivos texto ou XML e também por mapeamento de objetos. O DataSet é visto pelos programadores ADO como um recordset vitaminado, mas ele é muito mais do que isso. O Recordset é capaz de armazenar apenas um conjunto de dados. O DataSet pode armazenar vários conjuntos, organizados em DataTables. DataTables são estruturas em memória que reproduzem as funcionalidades de uma tabela de um banco de dados. DataTables podem ter restrições (como chaves primárias, por exemplo), através da coleção Constraints e podem ser relacionadas entre si, através de relações, que são adicionadas à coleção Relations. Após obtidos, os dados permanecem no DataSet e é feita a desconexão com a base de dados, conexão que só voltará a ser estabelecida quando for necessária alguma operação de escrita na base ou quando se desejar obter novamente os dados. Nota Tenha sempre em mente que o DataSet é preenchido com todos os registros retornados pelo comando SQL que foi colocado no DataAdapter. Se esse comando retornar um milhão de registros, serão trafegados um milhão de registros pela rede de uma só vez, e um milhão de registros que serão alocados em uma estrutura de memória. 87

88 Se a sua aplicação trabalhava com resultsets grandes, que também eram custosos em termos dde processamento e alocação de cursor do lado do servidor, pode ser esta a hora de rever o seu modelo de acesso a dados. No ADO.NET 2.0 há novidades, como a possibilidade de usar um DataReader em um DataTable, updates em batch, entre outros. Populando e iterando por um DataSet O exemplo abaixo ilustra um exemplo típico de um DataSet e um DataAdapter: OleDbConnection cn = new OleDbConnection(); cn.connectionstring = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=c:\\nwind.mdb;User Id=admin;Password=;"; OleDbDataAdapter da = new OleDbDataAdapter("select * from Customers", cn); DataSet ds = new DataSet("Clientes"); da.fill(ds, "Clientes"); foreach( DataRow dr in ds.tables["clientes"].rows) Console.WriteLine("" + dr["companyname"] + ":" + dr["contactname"]); Primeiro é criada a conexão com a base de dados de teste note que a base de dados de exemplo NWind.mdb deve estar no diretório-raiz; caso ela esteja em outro diretório basta alterar a string de conexão). Depois, é criado um DataAdapter, que recebe o comando SQL e a conexão. O comando da.fill instrui o DataAdapter a conectar-se ao banco executar o SQL e preencher o DataTable Clientes do DataSet ds com os dados obtidos como resultado. Note também que usamos um loop foreach para iterar ao longo de uma DataTable do DataSet. Esse tipo de construção é robusto e evita erros com índices, o que por vezes acontecia quando usávamos construções de loops For que iteravam usando, por exemplo, propriedades como Count. Filtrando dados em um DataSet Embora os dados devam ser filtrados preferencialmente na origem dos dados (usando cláusulas where) e deva ser repassado ao DataSet apenas os registros que correspondam a uma regra, muitas vezes se deseja filtrar dados que já estão em um DataSet. 88

89 Para filtrar os dados em um DataSet existe o método Select, que recebe como parâmetro um String contendo cláusulas como as que usaríamos em um where de uma instrução SQL. O exemplo abaixo mostra como filtrar os registros cuja coluna CustomerID começa com A : DataRow[] rows; rows = ds.tables["clientes"].select("customerid LIKE 'A%'"); A maioria das regras de sintaxe do SQL se aplica ao método Select de um DataSet, bem como os comandos: And, Or, Not, >, <, <>, =, CONVERT, LEN, ISNULL, IIF são exemplos. Consulte a documentação do DataSet para ver todas as opções. Existem também métodos Select sobrecarregados que permitem ordenar os campos como em uma instrução ORDER BY do SQL ou ainda filtrar de acordo com o RowState. O exemplo abaixo filtra os clientes brasileiros os e ordena em ordem alfabética descrescente: DataRow[] rows; rows = ds.tables["clientes"].select("county = 'Brazil'", "CustomerName DESC"); Procurando por uma informação em um DataSet Existe uma outra forma de procurar por um determinado registro que é usada apenas para buscas no campo de chave primária. O exemplo abaixo demonstra o seu uso: DataRow[] rows; rows = ds.tables["clientes"].rows.find("koene"); DataViews Assim como as Views de um banco de dados permitem criar uma estrutura de dados filtrados e ordenados a partir de um DataTable. Nota Há diferenças entre o uso do método Select do DataTable e um DataView. O Select retorna um conjunto de linhas copiadas de um DataTable, enquanto o DataView continua ligado ao DataTable, e todas as alterações que forem feitas em um serão refletidas no outro. 89

90 Além disso, o DataView pode ser usado como DataSource de controles visuais, como um DataGrid ou um TextBox, entre outros. O exemplo abaixo filtra os registros cujo CustomerID começa com A e ordena pelo campo CustomerName usando um DataView. DataSource para um DataGridView. Note que o DataView também serve como OleDbConnection cn = new OleDbConnection(); cn.connectionstring = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=c:\\nwind.mdb;User Id=admin;Password=;"; OleDbDataAdapter da = new OleDbDataAdapter("select * from Customers", cn); DataSet ds = new DataSet("Clientes"); da.fill(ds, "Clientes"); DataView dv = new DataView(); dv.table = ds.tables["clientes"]; dv.rowfilter = "CustomerID LIKE 'A%'"; dv.sort = "CutomerName ASC"; DataGridView1.DataSource = dv; Atualizando o banco com informações do DataSet Para atualizar um banco de dados, devemos usar um DataAdapter para que ele faça a conexão com o banco de dados e faça as operações necessárias. Para tanto, devemos configurar as instruções de INSERT, UPDATE e DELETE apropriadamente, usando as respectivas propriedades InsertCommand, UpdateCommand e DeleteCommand do DataAdapter, bem como os seus parâmetros. A cada linha de um DataSet é atribuída uma propriedade RowState, que reflete o estado dos dados daquela determinada linha. Os valores possíveis são: Added Deleted Detached Modified A linha foi adicionada e AcceptChanges não foi chamado A linha foi marcada para ser apagada Acontece imediatamente depois de a linha ter sido criada mas ainda não foi adicionada à coleção de linhas do DataTable A linha foi modificada desde o último AcceptChanges 90

91 Unchanged A linha permanece a mesma desde o último AcceptChanges O exemplo abaixo ilustra esse processo, supondo que já exista um objeto Connection instanciado e que os únicos campos do DataSet que sofrem atualização são CompanyName e ContactID: StringBuilder sb = new StringBuilder(); sb.append("update Customers "); sb.append("set CompanyName "); sb.append(" ContactName "); sb.append("where (CustomerID da.updatecommand = new SqlCommand(sb.ToString(), cn); da.updatecommand.parameters.add("@companyname", SqlDbType.VarChar, 255, "CompanyName"); da.updatecommand.parameters.add("@contactname", SqlDbType.VarChar, 255, "ContactName"); da.updatecommand.parameters.add("@customerid", SqlDbType.VarChar, 255, "CustomerId"); da.update(ds.tables("clientes")); Note a sintaxe que foi usada: foram criados parâmetros, que começam para cada variável que usaremos na atualização. Logo após, para cada um desses parâmetros, informamos um tipo e tamanho de campo (no caso, usamos em todos o tipo SqlDbType.VarChar com tamanho 255) e, por fim, indicamos a que coluna do DataSet o parâmetro corresponde. Por último, a instrução Update atualiza a base de dados. Todos os registros com RowState Modified serão atualizados na base. Acessando arquivos XML Esta seção tem por fim apenas ilustrar como usar um DataSet simples que lê ou que grava em arquivos XML. Gravando arquivos XML a partir de um DataSet A classe DataSet contém dois métodos para serem usados na escrita de arquivos XML: WriteXML e WriteXMLSchema. 91

92 O método WriteXMLSchema permite que um DataTable populado possa ter o seu esquema (definições de campos) salvos em um arquivo. O método WriteXML permite que os dados de um DataTable sejam gravados em um arquivo XML. O exemplo abaixo ilustra os dois métodos, rode-o e veja os resultados nos dois arquivos de saída: OleDbConnection cn = new OleDbConnection(); cn.connectionstring = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=c:\\nwind.mdb;User Id=admin;Password=;"; OleDbDataAdapter da = new OleDbDataAdapter("select * from Customers", cn); DataSet ds = new DataSet("Clientes"); da.fill(ds, "Clientes"); DataView dv = new DataView(); dv.table = ds.tables["clientes"]; dv.rowfilter = "CustomerID LIKE 'A%'"; dv.sort = "CutomerName ASC"; ds.writexml("c:\\saida.xml"); ds.writexmlschema("c:\\saida.xsd"); cn.close(); Lendo arquivos XML em um Dataset A leitura de um arquivo XML requer que seja informado não só o arquivo de dados, mas também um arquivo contendo as definições de cada campo. Caso não exista, o objeto DataSet tenta inferir o esquema, ou seja, tenta criar sozinho o esquema, o que funciona na maioria dos casos. Para ler o esquema, usa-se o método ReadXmlSchema, e para ler o arquivo XML, ReadXml. O código abaixo lê um arquivo XML e popula um DataGridView com os dados obtidos. DataSet ds = new DataSet(); ds.readxmlschema("c:\\saida.xsd"); ds.readxml("c:\\saida.xml"); DataGridView1.DataSource = ds.tables(0); 92

93 Experimente tirar a segunda linha (que chama ReadXmlSchema) do código e veja que o objeto DataSet foi capaz de inferir sozinho o esquema do XML. Trabalhando com nulos Os campos de um banco de dados têm que ter uma forma de indicar se estão ou não vazios. Um campo do tipo VarChar poderia conter uma string para indicar isso, mas o que conteria um campo Int? 0? E quando precisarmos representar o valor zero? Para isso, foi desenvolvido o tipo Null para representar que o conteúdo de um campo é nulo. Entretanto, o significado de nulo em um banco de dados e no.net são diferentes. No.NET, um nulo significa apenas que a variável não aponta para lugar nenhum da memória. E como fazemos essa conversão? Ao fazer conversão de um dado nulo para uma variável.net, há três formas de fazer o tratamento: 1. IsDbNull: a função IsDbNull retorna True se o valor a ser verificado contiver nulo; 2. DbNull.Value: deve ser usado em uma comparação, como no exemplo: If (a == DbNull.Value) Fazendo conversão com ToString(): nesse caso, o método retornará uma string vazia se exisitir um valor nulo. Revisão Neste capítulo, estudamos o funcionamento do ADO.NET, o novo pacote de classes que expõe serviços de acesso a dados para a programação.net. Vimos um pouco sobre os diferentes DataProviders que acompanham o.net 2.0 e qual o novo modelo de objetos do ADO.NET. Além disso, estudamos o importante objeto DataSet, que permite trabalhar de forma desconectada com uma cópia dos dados na memória. Para completar, vimos como usar o DataSet para buscar dados de um arquivo XML, e como lidar com dados nulos. 93

94 Capítulo 9 Trabalhando com Windows Forms Objetivos Neste capítulo, iremos estudar um pouco sobre programação para Windows no C# 2.0, com o objetivo de desenvolver no leitor a curiosidade de experimentar e aprender como funciona. Vamos mostrar como é possível trabalhar com janelas, usando formulário MDI, como adicionar controles aos seus formulários, como definir uma janela Master, da qual outros formulários herdam e como tratar eventos disparados pelo usuário. Além disso, como algumas vezes é necessário desenvolver controles personalizados, falaremos como criar um User Control, e utilizar o mesmo nos seus formulários. Por fim, trataremos um pouco sobre acesso a dados em um Windows Form. Formulários MDI Um formulário MDI (Multiple Document Interface) permite que sejam abertos e confinados outros formulários dentro dele, como ilustrado: Para criar o formulário-pai, pode ser feito de duas formas: 94

95 1. Usando o assistente, que está acessível ao se clicar no projeto, escolhendo a opção Add e depois New Item. Na janela que se abrirá, uma das opções é o MDI Parent Form. Dessa forma é criado um formulário com vários componentes já configurados, como menu e status bar entre outros; 2. Criando um novo formulário e marcando a propriedade IsMDIParent com True. Para chamar formulários-filho, basta criar formulários comuns e, quando eles forem abertos pelo formuário MDI principal, a partir de um menu, botão, eventos ou outra forma, deve ser usado código similar ao apresentado abaixo: ' o formulário-filho foi chamado de Form1 Form1 f1 = new Form1(); ' determina que o formulário-pai é o formulário ' em que está sendo feita a chamada f1.mdiparent = this; ' opcional, faz com que o formulário inicie maximizado f1.windowstate = FormWindowState.Maximized; ' abre o formulário f1.show(); Herança de formulários Formulários podem também ser herdados, permitindo que se desenhe um formulário master e que qualquer mudança seja replicada para todos os seus descendentes. Para criar um novo formulário e herdar as características de outro formulário, basta acrescentar o comando Inherits à declaração do formulário, como no exemplo abaixo: public class Form2 : Project1.Form1 Nota Perceba que, conforme ilustrado, o deve ser informado o nome do projeto e o nome do formulário a ser herdado. Caso seja informado apenas o nome do formulário, o próprio Visual Studio gerará um erro e mostrará a sugestão para fazer com que o código funcione. 95

96 No exemplo acima, todos os controles e propriedades de Form1 serão herdados por Form2, e as propriedades dos controles que foram herdados não poderão ser alteradas. Podemos, entretanto, sobrescrever métodos e propriedades declarados em Form1 que foram declarados com Overridable. User Controls User Controls são controles ou grupos de controles criados pelo desenvolvedor. Em relação aos controles ActiveX usados anteriormente, os User Controls são mais completos e são mais fáceis de distribuir, de usar e serem extendidos, além de serem aderentes à plataforma.net. Com os user controls podem ser criados modelos de controles que podem ser repetidos e aplicados em outros formulários, a partir da Toolbox do Visual Studio ou instanciados via código na aplicação. User controls trazem grandes vantagens e facilidades: eles podem encapsular controles ou grupos de controles que são usados recorrentemente em nossa aplicação. Se tivermos um mesmo user control espalhado ao longo de vários formulários, se fizermos uma alteração no user control, essa mudança será replicada para todos os formulários que o usarem. Embora isso possa parecer uma grande vantagem, também traz um inconveniente: caso você, por exemplo, precise deixar o seu user control maior em tamanho de tela, isso pode afetar o lay-out de formulários que já o usavam. Projete o user control com cuidado para isso não acontecer. Adicionando um controle programaticamente Adicionamos um controle programaticamente, adicionando o mesmo à coleção de controles do Formulário: this.controls.add(f1); Disparando eventos de um controle Em controles (ou user controls) criados por nós ou herdados podemos criar novos eventos para adicionar maior interação entre o formulário ou os containers e o nosso controle (ou user control). 96

97 Para criar um evento, precisamos primeiro criar um Delegate. Um delegate funciona como uma referência para um método. Ele deve ser declarado fora da classe que irá dispará-lo, e deve ter visibilidade pública. public delegate void MyEventHandler(object sender, EventArgs e); Em seguida, dentro da classe declare um evento do tipo do delegate criado: public event MyEventHandler MyEvent; Para que a sua classe dispare esse evento, você precisa agora chamar o evento criado, como no exemplo: private void btnhelloworld_click(object sender, EventArgs e) MyEvent(this, new EventArgs()); Por fim, quando você for consumir o controle, você precisa indicar qual método será disparado quando o evento ocorrer: mycontrol1.myevent += new MyEventHandler(myControl1_MyEvent); A próxima seção exemplifica com código o uso de user controls e de eventos. Lab: Criando um User Control O exemplo que será seguido aqui é um controle simples de formulário de login, contendo uma caixa de texto para que o usuário entre o seu login e outra para a sua senha, uma label para cada caixa de texto e um label que mostrará mensagens de erro e um botão Login. A lógica e os dados de autenticação serão, apenas para esse exemplo, embutidos no código para fins didáticos, mas saiba que essa é uma prática que nunca deve ser usada em aplicações que serão usadas em produção. O controle avisará o usuário quando for feito o login ou quando houver um erro, e isso será feito através de eventos. Para começar, adicione um novo Windows Form chamado FormLogin. Adicione, também, um User Control chamado UCLogin (Para criar um novo User Control, 97

98 usando o Solution Explorer, clique no projeto com o botão direito do mouse e clique em Add e logo em seguida em User Control). Agora, adicione ao seu controle: Controle Propriedade Valor Label Text Usuário: Label Text Senha: TextBox (Name) txtusuario TextBox (Name) txtsenha PasswordChar * Button (Name) btnlogar Text Logar Fora da sua classe, crie agora 2 delegates: UsuarioLogadoEventHandler Evento que será disparado quando o usuário se logar corretamente. LoginInvalidoEventHandler Evento que será disparado quando o login e/ou a senha forem inválidos. Crie, agora dentro da classe do controle, 2 eventos: OnUsuarioLogado; OnLoginInvalido....que irão disparar os delegates respectivos. Por fim, crie uma lógica de negócios que aceite: Usuário: AdoptionLab ; Senha: AdoptionLab...como resposta correta a que dispara o evento OnUsuarioLogado e que qualquer outra resposta dispare o evento OnLoginInvalido. Depois de criado o user control, faça um Build na Solution que estamos usando. Verifique que o user control que criamos deverá aparecer no ínício da Toolbox: 98

99 O nosso user control é um novo controle que pode ser arrastado para um formulário e pode ter as propriedades verificadas e confguradas através da caixa de propriedades. Arraste o nosso controle para o FormLogin. Observe agora as propriedades do controle criado. Veja também que na lista de eventos aparecem os dois eventos por nós criados: Através desses eventos, podemos criar métodos que serão chamados quando um deles for disparado pelo user control que criamos. Clique duas vezes em cada um dos eventos criados, para gerar automaticamente o código de tratamento do evento. Pode-se também gerar esses eventos de forma manual, conforme explicado no tópico Disparando eventos de um controle. Agora insira código de validação para cada um dos eventos, que mostra uma mensagem na tela caso o usuário tenha logado corretamente, ou não. Agora, existe mais um pequeno passo necessário antes que possamos prosseguir. Se executarmos a nossa aplicação, ele irá automaticamente chamar o Form1. Não queremos isso. Como fazemos então? 99

100 Clique duas vezes na classe Program.cs. No método Main, comente a linha aonde está escrito: Application.Run(new Form1()); E insira uma nova linha, escrita: Application.Run(new FormLogin()); Isso fará com que a sua aplicação inicie agora pelo FormLogin. Rode a sua aplicação e veja o resultado. Após esse teste, volte a linha do Program.cs para o valor original. O código fonte com o resultado esperado desse lab está contido no CD. Respondendo a eventos de teclado É comum encontrar no mercado sistemas que precisem responder a eventos de teclado, quer para validar a entrada, quer para tornar mais fácil a navegabilidade. Eventos de teclado podem ser respondidos usando os já conhecidos eventos de KeyDown, KeyUp, KeyPressed, TextChanged. Data Binding Através do DataBinding, podemos vincular controles a objetos que manipulam dados, tornando fácil a navegação e a alteração de informações nele contidas. DataSource Diversos controles que vêm por padrão com o.net já possuem características que tornam possível associá-los diretamente com as fontes de dados (através de um 100

101 DataSet, um ArrayList, etc), facilitando o processo de manipulação e exibição desses dados. Para facilitar a manipulação dos dados a partir de fontes de dados, o.net traz o controle DataGridView. Esse controle é o controle mais poderoso contido no.net para trabalhar com dados, e será estudado nas próximas seções. Alguns controles (no caso, a ComboBox e a ListBox) possuem 3 propriedades muito importantes, que facilitam a vinculação: DataSource Define a fonte de dados. DisplayMember Define o campo que será usado como valor a ser exibido. ValueMember Define o valor do campo (uso interno). Vejamos um exemplo, de como popular um ListBox (o mesmo princípio se aplica a uma ComboBox): // Esta parte você já viu... string connectionstring = "Data Source=CAIOWAA\\SQLEXPRESS;Initial " + "Catalog=Northwind;Integrated Security=True"; SqlConnection cn = new SqlConnection(connectionString); SqlDataAdapter da = new SqlDataAdapter(); da.selectcommand = new SqlCommand("SELECT * FROM Customers", cn); DataSet ds = new DataSet(); da.fill(ds); // Essa parte é responsável pela conexão. lstcustomers.datasource = ds.tables[0]; lstcustomers.displaymember = "ContactName"; lstcustomers.valuemember = "CustomerID"; Esses controles possuem as seguintes propriedades: SelectedItem Essa propriedade retorna um objeto que representa o item da seleção. SelectedValue Esta propriedade representa o valor do item selecionado (a propriedade configurada por ValueMember). 101

102 DataBinding Entretanto, esse não é o único modo de conectar um controle a uma fonte de dados. Como dito anteriormente, poucos controles expõe a propriedade DataSource. Se for assim, então como devo fazer? Os controles Windows Forms (assim como as classes que herdam de UserControl) implementam também uma propriedade chamada DataBindings. Essa propriedade retorna uma coleção de vínculos (bindings) entre o controle a alguma fonte de dados. Usando o método Add da coleção, podemos adicionar vínculos de nosso controle com diversas fontes de dados. O método DataBindings.Add aceita diversos parâmetros, dentre os quais os mais importantes para nós são: propertyname Nome, no formato texto, da propriedade do controle que será vinculada; datasource Objeto da fonte de dados; datamember Campo da fonte de dados que será vinculada. Vamos ver agora como fazer o binding: textbox1.databindings.add("text", ds.tables[0], "ContactName"); Nesse caso, vinculamos a propriedade Text de nosso textbox à fonte ds.tables[0], e ao campo ContactName. BindingNavigator Se você implementou o exemplo da TextBox, deve ter verificado um problema: o vínculo foi formado, mas apenas o primeiro campo apareceu. Como eu faço para navegar nos registros? Com essa finalidade, o.net traz para nós o controle BindingNavigator. A função desse controle é exatamente essa: permitir a navegação nos dados. Esse controle está contido na ToolBox do Visual Studio: 102

103 Para implementar um BindingNavigator, precisamos primeiro implementar um BindingSource. O BindingSource define qual a fonte de dados à qual iremos nos conectar. Ou seja, ele define: DataSource Fonte de dados. DataMember Subgrupo dentro da fonte de dados. Em geral, a tabela. Enquanto isso, o BindingNavigator cria uma barra de ferramentas, que permite navegar nos registros da fonte de dados: Vamos ver um exemplo de implementação: string connectionstring = "Data Source=CAIOWAA\\SQLEXPRESS;Initial " + "Catalog=Northwind;Integrated Security=True"; SqlConnection cn = new SqlConnection(connectionString); SqlDataAdapter da = new SqlDataAdapter(); da.selectcommand = new SqlCommand("SELECT * FROM Customers", cn); DataSet ds = new DataSet(); da.fill(ds); bindingsource1.datasource = ds.tables[0]; bindingnavigator1.bindingsource = bindingsource1; textbox1.databindings.add("text", bindingsource1, "ContactName"); Lab: Data Binding Vamos usar um exemplo para demonstrar as funcionalidades do DataBind. Abra o projeto WindowsApplicationCS, e adicione um novo Form chamado FormDataBinding.cs. Agora, abra o Project.cs, e no Application.Run, altere para: Application.Run(new FormDataBinding()); 103

104 Nosso objetivo será obter os dados da base NorthWind, e gerar um formulário que permita visualizar ou alterar os dados de um cliente. Para isso, abra a janela DataSources (menu Data > Show Data Sources ). Clique em Add New Data Source.... Na janela que se abre, selecione Database e clique em Next >. Na tela Choose Your Data Connection, clique em New Connection... para gerar uma nova conexão com uma base de dados. Escolha conexão a um servidor SQL. Na tela Add Connection......em Server Name, aponte o nome do banco de dados configurado no seu sistema. Na caixa Select or enter a database name:, selecione o banco Northwind, e clique em OK. De volta á tela Choose Your Data Connection, clique em Next>. Na tela Save the Connection String to the Application Configuration File, clique Next>. 104

105 Agora, você verá uma tela chamada Choose Your Database Objects, aonde você poderá escolher quais os objetos do banco você pretende utilizar. Expanda a opção Tables, e marque a opção Customers. Isso irá, automaticamente, fazer com que todos os objetos dessa tabela sejam adicionados ao DataSet tipado que será criado. Clique em Finish. Você deve ter agora algo parecido com isso na sua janela Data Sources. Em Customers, selecione a seta para baixo, e altere o tipo para Details. Agora, arraste o objeto Customers para o seu formulário. Repare que todos os campos do DataSet criado são automaticamente copiados para dentro do formulário. Além disso, note também que já foram gerados, automaticamente, uma instância do DataSet (northwinddataset), uma binding source (customersdatasource) e um data adapter (customersdataadapter). 105

106 Todos os controles TextBox já estão automaticamente vinculados à sua BindingSource. Agora, arraste um controle Binding Navigator : Propriedade (Name) BindingSource Valor customersbindingnavigator customersbindingsource Agora, arraste um botão para o seu Form: Propriedade (Name) Text Valor btngravar Gravar Clique agora 2 vezes no botão btngravar, e no evento Click do botão, insira o seguinte código: 106

107 DialogResult result = MessageBox.Show("Salvar Alterações?", "DataBinding", MessageBoxButtons.YesNo); if (result == DialogResult.Yes) customersbindingsource.movelast(); int rows = customerstableadapter.update(northwinddataset); if (rows > 0) MessageBox.Show("Alterações feitas com sucesso!", "DataBinding"); Execute agora a sua aplicação, e verifique o resultado: O resultado desse lab se encontra disponível no CD do treinamento. DataGridView O DataGrid inclui não só a facilidade de, a partir de um recordset, popular a sua interface gráfica, mas também incluir e permitir a alteração de dados ali mostrados. Quando o desenvolvedor necessitava de maiores funcionalidades, como ordenação, formatação, era necessário escrever código, muitas vezes extenso, ou depender de componentes de terceiros. O DataGridView apareceu na versão 2.0 do framework.net e traz consigo características que facilitam muito a vida do desenvolvedor.net: auto-ajuste de linhas e colunas, estilos de célula, auto-organização de colunas, formatação, entre outras. 107

108 Populando um DataGridView Popular um DataGridView a partir de um DataSet é uma tarefa simples. Basta adicionar o DataSet à propriedade DataSource do DataGridView. O código abaixo, implementado de forma similar ao anterior, ilustra melhor esse processo: // Busco a string de conexão do arquivo de configuração. Properties.Settings setting = new Properties.Settings(); SqlConnection cn = new SqlConnection(setting.NorthwindConnectionString); SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Employees", cn); DataSet ds = new DataSet(); da.fill(ds, "Empregados"); datagridview1.datasource = ds; datagridview1.datamember = "Empregados"; Ativando a ordenação automática Para ativar a ordenação automática, que permite que o usuário possa alternar a odenação ascendente/descendente ao clicar em cima de uma coluna, basta marcar a propriedade AllowUserToOrderColumns (o que pode também ser feito em tempo de design usando a aba Propertires do DataGridView): datagridview1.allowusertoordercolumns = true; Ativando o auto-ajuste de linhas e colunas Para que todas as colunas sejam auto-ajustadas, use: datagridview1.autoresizecolumns; Para que uma coluna seja auto-ajustada, use: datagridview1.autoresizecolumn(<índice>);.. onde <índice> é o número da coluna que será auto-ajustada. Para que todas as linhas sejam auto-ajustadas, use: datagridview1.autoresizerows(); 108

109 Para que apenas uma linha seja auto-ajustada, use: datagridview1.autoresizerow(<índice>); Renomeando as colunas A chamada abaixo mostra como renomear uma coluna a partir do seu nome: datagridview.columns["employeeid"].headertext = "ID"; Formatando colunas Para formatar colunas, podemos usar os mesmos códigos de formatação que foram vistos no capítulo 3. No exemplo abaixo, a coluna UnitPrice terá a formatação de valores monetários que foi escolhida nas Configurações Regionais do Windows. A segunda linha, que formata a coluna UnitsInStock, usa uma formatação customizada, preenchendo com zeros as duas casas à esquerda e à direita do ponto: datagridview1.columns["unitprice"].defaultcellstyle.format = "C"; datagridview1.columns["unitsinstock"].defaultcellstyle.format = "##00.00 ; Mudando o estilo de acordo com uma condição O exemplo abaixo mostra como deixar com fundo amarelo a célula HiredDate de todos os funcionários que foram contratados de 1993 para a frente. Para que possamos fazer a alteração, basta escrever um método que manipule o evento DataGridView.CellFormatting e usar os DataGridViewCellFormattingEventArgs para termos acesso aos dados da célula: private void datagridview1_cellformatting(object sender, DataGridViewCellFormattingEventArgs e) if (datagridview1.columns[e.columnindex].name.equals("hiredate")) object blah = e.value; 109

110 if (e.value!= null) if (e.value!= DBNull.Value) if (((DateTime)e.Value).Year > 1992) e.cellstyle.backcolor = Color.Yellow; Fazendo um DataGridView zebrado Para fazer um DataGridView zebrado, basta usar definir um estilo e configurá-lo na propriedade AlternatingRowsDefaultCellStyle. Quando o DataGridView for renderizado, o próprio componente se encarrega de alternar entre o DefaultStyle e o AlternatingStyle. O exemplo abaixo, adicionado ao DataGridView que viemos trabalhando, faz com que as linhas alternadas sejam preenchidas com fundo cinza claro: datagridview1.alternatingrowsdefaultcellstyle.backcolor = Color.LightGray; Lendo eventos de seleção O exemplo abaixo mostra um método que manipula o evento Click do DataGridView, e mostra a mensagem com o nome de todos os funcionários selecionados: private void datagridview1_click(object sender, EventArgs e) foreach (DataGridViewCell cell in datagridview1.selectedcells) DataGridViewRow row = datagridview1.rows[cell.rowindex]; string firstname = row.cells["firstname"].value.tostring(); string lastname = row.cells["lastname"].value.tostring(); string title = row.cells["titleofcourtesy"].value.tostring(); MessageBox.Show( title + " " + firstname + " " + lastname ); 110

111 Oferecendo uma lista de opções em um ListBox Agora, e se um dos campos que estamos trabalhando contém um código para um valor em uma outra tabela (uma chave estrangeira) e precisamos que, ao invés de exibir o código, precisemos exibir o valor? No exemplo abaixo, utilizamos uma tabela chamada EmployeeTerritories, que contém o relacionamento entre os territórios atendidos e os funcionários que o atendem. Criamos colunas customizadas, para fazer o relacionamento. private void FormDataGridView_Load(object sender, EventArgs e) // Busco a string de conexão do arquivo de configuração. Properties.Settings setting = new Properties.Settings(); SqlConnection cn = new SqlConnection(setting.NorthwindConnectionString); // Um adapter para cada query. SqlDataAdapter daemployees = new SqlDataAdapter("SELECT * FROM " + "Employees", cn); SqlDataAdapter daterritories = new SqlDataAdapter("SELECT * FROM " + "Territories", cn); SqlDataAdapter daemployeeterritories = new SqlDataAdapter("SELECT *"+ " FROM EmployeeTerritories", cn); DataSet ds = new DataSet(); daemployees.fill(ds, "Empregados"); daterritories.fill(ds, "Territorios"); daemployeeterritories.fill(ds, "TerritoriosEmpregados"); // Vinculo o DGV à tabela de relacionamento. datagridview1.datasource = ds; datagridview1.datamember = "TerritoriosEmpregados"; // Apago as colunas de índice, que não serão usadas. datagridview1.columns.clear(); // Crio uma coluna contendo uma DropDown com os territórios. DataGridViewComboBoxColumn colterritories = new DataGridViewComboBoxColumn(); colterritories.displayindex = 0; colterritories.headertext = "Territorio"; colterritories.datapropertyname = "TerritoryID"; 111

112 colterritories.datasource = ds.tables["territorios"]; colterritories.displaymember = "TerritoryDescription"; colterritories.valuemember = "TerritoryID"; datagridview1.columns.add(colterritories); // Crio uma coluna contendo uma DropDown com os funcionários. DataGridViewComboBoxColumn colemployees = new DataGridViewComboBoxColumn(); colemployees.displayindex = 1; colemployees.headertext = "Empregado"; colemployees.datapropertyname = "EmployeeID"; colemployees.datasource = ds.tables["empregados"]; colemployees.displaymember = "LastName"; colemployees.valuemember = "EmployeeID"; datagridview1.columns.add(colemployees); // Recalcula o tamanho das colunas. datagridview1.autoresizecolumns(); Formulários Master/Detail Formulários Master/Details são aqueles que mostram os dados separados em dois grupos: o principal (Master) e o de detalhes (Detail). Quando escolhemos um registro no principal, o de detalhes se atualiza de acordo com a relação que existe entre os dois. DataRelation É importante, nesse ponto, falar um pouco sobre o objeto DataRelation. O DataRelation é um objeto do namespace System.Data, que define uma relação entre duas colunas de duas tabelas diferentes contidas em um DataSet. Ele aceita diversos parâmetros, mas os principais são: relationname Uma string, contendo um nome para a relação. parentcolumn Recebe uma DataColumn (coluna do DataSet), que representa a coluna pai. childcolumn Recebe uma DataColumn (coluna do DataSet), que representa a coluna filha. Como exemplo: 112

113 DataColumn colpai = ds.tables["empregados"].columns["employeeid"]; DataColumn colfilho = ds.tables["tempregados"].columns["employeeid"]; DataRelation rel = new DataRelation("RelTEmpregados", colpai, colfilho); Estratégia do Master/Detail Com o componentes BindingSource, ficou muito fácil fazer relações Master/Detail. O que deve ser feito é: 1. criar um objeto Connection e conectar à base; 2. criar dois DataAdapters, um para cada tabela; 3. criar um DataSet que abrigará as duas tabelas e sua relação; 4. preencher dois DataTables do DataSet usando os dois DataAdapters; 5. criar um DataRelation, que fará a relação pai/filho das tabelas; 6. criar dois BindingSources; 7. um dos BindingSources receberá como DataSource o DataSet, e como DataMember o DataTable com a tabela-pai; 8. o outro BindingSource receberá como DataSource o BindingSource anterior, que contém os dados da tabela-pai, e o DataMember será o DataRelation que foi criado. Lab: Relacionamentos e Master-Detail Vamos ver como utilizar os relacionamentos, e como trabalhar com dados no formato Master-Detail. Para isso, vamos utilizar o banco Northwind, e criar a nossa aplicação. Abra a solução WindowsApplicationCS, criada anteriormente. Adicione um formulário, chamado FormDataGridView.cs. Como nas outras vezes, edite o arquivo Program.cs, e altere a linha do Application.Run para que ele execute o seu código: Application.Run(new FormDataGridView()); 113

114 Lembre-se de, no começo da classe, importar o namespace System.Data.SqlClient. Nesse formulário, adicione os seguintes controles: Controle Propriedade Valor Label Text Funcionário: Label Text Territórios Atendidos: ComboBox (Name) cmbfuncionario DropDownStyle DropDownList DataGridView (Name) dgvterritorios EditMode EditProgrammatically (Não temos interesse em permitir a edição nesse momento). Agora, você deve ter um visual mais ou menos como o seguinte: Crie uma conexão e os adapters necessários para executar as seguintes buscas no banco e gravar os dados em um DataSet: SELECT EmployeeID, LastName + ', ' + FirstName AS [Name] FROM dbo.employees ORDER BY Name ASC SELECT FROM TerritoryID, TerritoryDescription dbo.territories SELECT * FROM EmployeeTerritories Crie um DataRelation, relacionando as tabelas Employees e EmployeeTerritories, através do campo EmployeeID, como segue: 114

115 DataColumn colpai = ds.tables["empregados"].columns["employeeid"]; DataColumn colfilho = ds.tables["tempregados"].columns["employeeid"]; DataRelation rel = new DataRelation("RelTEmpregados", colpai, colfilho); ds.relations.add(rel); Agora, adicione via código 2 objetos BindingSource, um que irá apontar para a tabela Employees e outro que irá apontar para EmployeeTerritories: BindingSource bsempregados = new BindingSource(); bsempregados.datasource = ds; bsempregados.datamember = "Empregados"; BindingSource bsterritorios = new BindingSource(); bsterritorios.datasource = bsempregados; bsterritorios.datamember = "RelTEmpregados"; Note que, no caso do bsterritorios, ele está apontando o DataSource para o bsempregados, e o DataMember para o nome que foi dado para o relacionamento (RelTEmpregados). Com isso, vinculamos uma fonte à outra. Vincule agora a sua ComboBox à fonte bsempregados, e o DataGridView à fonte bsterritorios. Com isso agora eles estão corretamente relacionados. Entretanto, note que ele não ficou visualmente agradável. O que quer dizer cada TerritoryID? Além disso, o EmployeeID é desnecessário não significa nada para o usuário. Vamos melhorar o nosso programa, trabalhando os dados do Grid. A primeira coisa a fazer é limpar o nosso Grid. Para isso, utilizamos o método Clear, da coleção Columns do DataGridView. 115

116 Nosso próximo passo é adicionar programaticamente uma coluna, que receba o TerritoryID do grid e exiba o texto. Fazemos isso com uma coluna do tipo DataGridViewComboBoxColumn: DataGridViewComboBoxColumn colterritories = new DataGridViewComboBoxColumn(); colterritories.displayindex = 0; colterritories.headertext = "Territorio"; colterritories.datapropertyname = "TerritoryID"; colterritories.datasource = ds.tables["territorios"]; colterritories.displaymember = "TerritoryDescription"; colterritories.valuemember = "TerritoryID"; No exemplo, dissémos que a coluna irá receber a propriedade TerritoryID (DataPropertyName), e irá se conectar à fonte ds.tables["territorios"] (DataSource), e exibirá a coluna TerritoryDescription (DisplayMember). Entretanto, como não temos interesse que o usuário possa alterar os valores, seria bom forçarmos para que ele não possa selecionar outro valor na lista. Isso é feito com o comando: colterritories.displaystyle = DataGridViewComboBoxDisplayStyle.Nothing; Agora vamos adicionar a nossa coluna à coleção de colunas do grid, e mandar a coluna se auto-redimensionar automaticamente. Rode a sua aplicação e veja o resultado: O resultado está contido no CD. 116

117 Revisão Neste capítulo, foi mostrado como funciona um formulário MDI no C#, como funciona o DataBinding e falamos um pouco sobre o DataGridView e formulários Master/Detail. Esperamos que este capítulo tenha despertado no leitor a vontade de se aprofundar mais na programação Windows Forms. 117

118 Capítulo 10 Web Services Objetivos O termo Web Service vem se tornando um termo cada vez mais comum, quando se fala de aplicações distribuídas. Mas o que vem a ser um Web Service, e porque tanto se fala sobre isso? O objetivo desse capítulo é explicar ao leitor o que é um Web Service, qual o uso prático disso, como criar um Web Service simples, como consumir os seus dados e como fazer para distribuí-lo. Conceito: O que é um Web Service? De acordo com o W3C (World Wide Web Consortium), um Web Service é um sistema de software desenhado para suportar a interoperabilidade máquinamáquina através de uma rede. Se sua aplicação precisa se comunicar com outra aplicação (como Pocket PC, SmartPhone, SAP, etc) através da Internet e de forma transparente, você precisa de um Web Service. Web Services são os blocos de construção fundamentais na migração da computação local para a computação distribuída pela Internet. Para que seja possível a interoperabilidade entre sistemas distribuídos, ele se baseia em 3 padrões: 118

119 Ele expõe suas funcionalidades através de um protocolo padrão de rede, usualmente o SOAP (Simple Objet Access Protocol); Ele provê um meio de descrever suas interfaces, com detalhes suficientes para que seja possível a uma aplicação cliente conversar com eles. Esta descrição é feita por um documento XML chamado WSDL (Web Services Description Language). Um Web Services deve ser registrado, de forma que possíveis usuários possam localizá-lo facilmente. Isso é feito por um serviço chamado UDDI (Universal Discovery Description and Integration). Padrões abertos e o foco na comunicação e colaboração entre pessoas e aplicações estão criando um ambiente onde os Web Services XML estão se tornando a plataforma para integração de aplicações. Ou seja, os Web Services utilizam os protocolos padrão da internet, para que se torne possível uma comunicação transparente aplicação-aplicação. Mas quais são as vantagens de um Web Services? Web Services provê interoperabilidade entre várias aplicações, rodando em plataformas diferentes; Eles utilizam padrões e protocolos abertos; Os dados e formatos dos protocolos são baseados em texto, sempre que possível; Ele utiliza o protocolo HTTP como meio de troca de informações, o que permite que os dados sejam transferidos mesmo através de firewalls o que não seria possível através de chamadas RPC; Ele facilita a reutilização de código, concentrando o fornecimento de dados em uma única fonte; O acoplamento fraco provido permite uma abordagem distribuída. E quais são as desvantagens? 119

120 Ainda não existem protocolos que reforçam transações; Eles possuem uma performance fraca comparada com as chamadas RPC. Entre as plataformas que permitem a utilização de Web Services, temos: Axi e Jacarta Tomcat Server, parte do Apache project; ColdFusion, da Macromedia; Java Web Services Development Pack (JWSDP) da Sun; Servidores Microsoft.NET, da Microsoft; Websphere Application Server, da IBM; Web Application Server, da SAP; Oracle Application Server, da Oracle. Criando um Web Service O C# já possui um tipo de projeto específico para o desenvolvimento de Web Services, que encapsula a maior parte da complexidade do desenvolvimento dele. Nada melhor que um exemplo para verificarmos como isso funciona. Abra o Visual Studio 2005, selecione File > New > Web Site

121 Selecione ASP.NET Web Services, em Language selecione Visual C# e em Location digite Clique em OK. O Visual Studio irá abrir um novo projeto, que estará localizado por default na raiz do seu IIS (que, por default, é c:\inetpub\wwwroot). Você pode verificar que ele criou automaticamente um WebService chamado Service.asmx, que possui um método chamado HelloWorld(). Mande rodar sua aplicação (pressionando F5 ou clicando em janela será mostrada: ), e veja o resultado. A seguinte Mas o que isso significa? Na primeira vez que você rodar a sua aplicação, ela ainda não vai estar configurada para permitir a depuração do código. Na primeira vez em que mandamos a aplicação rodar, o sistema irá nos avisar disso, e perguntar se desejamos alterar o modo para permitir depuração. Deixe que ele altere o Web.config, clicando em ok. 121

122 Veja que, após termos clicado em OK, o Visual Studio abre uma janela do browser (Internet Explorer) aonde ele mostra o conteúdo do nosso Web Service. Aqui, podemos ver uma lista dos serviços disponíveis. No caso, apenas o método Hello World está disponível. Clique nele. Uma nova janela será aberta: 122

123 Aqui, temos a opção de preencher todos os parâmetros necessários para a invocação do método, e podemos chamá-lo clicando em Invoke. Como o Hello World não tem nenhum parâmetro, clique em Invoke. Podemos ver então qual foi a resposta que retornou quando executamos uma chamada ao nosso método, Hello World. Isso é o que o cliente de nosso web service vai receber como resposta um arquivo XML (por isso estudamos XML em um outro capítulo). Só que este é um exemplo muito simples é um Web Service que faz pouca coisa ainda. Vamos criar um outro Web Method (nome dos métodos fornecidos por um Web Service), que consome os dados de um banco de dados e retorna para o usuário. Clique no arquivo Service.asmx com o botão direito, e escolha Delete e confirme. Exclua também o seu arquivo de código, clicando em Service.vb e escolhendo Delete. Agora, clique com o botão direito no projeto, e selecione Add New Item. Selecione Web Service, e dê a ele o nome de NorthwindDataProvider.asmx. Preste agora atenção ao Web Method HelloWorld(). [WebMethod] public string HelloWorld() return "Hello World"; Existe algo diferente nele? Se você reparar, vai ver que, antes do método existe um atributo chamado WebMethod(). Esse atributo é o que faz com que o C# saiba que você quer que aquele método esteja disponível. 123

124 Vamos alterar a classe NorthwindDataProvider para conter o seguinte código: using System; using System.Web; using System.Collections; using System.Web.Services; using System.Web.Services.Protocols; using System.Data; using System.Data.SqlClient; /// <summary> /// Summary description for NorthwindDataProvider /// </summary> [WebService(Namespace = " [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class NorthwindDataProvider : System.Web.Services.WebService public NorthwindDataProvider () //Uncomment the following line if using designed components //InitializeComponent(); [WebMethod] public DataSet ObterCliente(string customerid) string connectionstring = "Data Source=(local)\\SQLEXPRESS; " + "Initial Catalog=Northwind;Integrated Security=True"; string sqlquery = "SELECT * FROM Customers "; sqlquery += "WHERE CustomerId='" + customerid + "'"; SqlConnection connection = null; SqlDataAdapter adapter = null; DataSet dscliente = new DataSet(); try connection = new SqlConnection(connectionString); connection.open(); adapter = new SqlDataAdapter(sqlQuery, connection); adapter.fill(dscliente); finally adapter = null; if( (connection!= null) && (connection.state!= ConnectionState.Closed) ) connection.close(); 124

125 connection = null; return dscliente; Essa função retorna todos os dados de um cliente, utilizando como filtro o id do usuário. Clique com o botão direito em NorthwindDataProvider.asmx, e selecione Set As Start Page. Agora vamos rodar a nossa aplicação, e verificar o seu funcionamento. Use o id ALFKI para verificar o que acontece. Consumindo um Web Service Vimos, na sessão anterior, como criar um Web Service que faz uma consulta a um banco de dados e disponibiliza essa informação. Mas como consumimos os dados de um Web Service? Vamos ver isso com um exemplo. Abra a solução WindowsApplicationCS. Adicione um novo Form FormWSConsumer.cs. Como nas outras vezes, edite o arquivo Program.cs, e altere a linha do Application.Run para que ele execute o seu código: Application.Run(new FormWSConsumer()); Agora, adicione os seguintes controles: 1 Label Altere a propriedade Text para Customer Id: ; 1 Textbox Altere a propriedade (Name) para txtcustomerid ; 1 Button Altere a propriedade (Name) para btnsearch, e a propriedade Text para Buscar ; 1 DataGridView Altere a propriedade (Name) para dgvcustomer. 125

126 Agora, clique com o botão direito no projeto, e selecione Add Web Reference.... Uma nova janela irá surgir. Em URL, digite e clique em Go. Ele irá buscar para verificar se o Web Service realmente existe. Em Web Reference name:, escreva NorthwindWS, e selecione Add Reference. Agora, clique com o botão direito no projeto, e selecione Build. Isso irá compilar o projeto, o que irá facilitar a inclusão do Web Service no código. Agora, clique 2 vezes no botão buscar. Você abrirá o método btnsearch_click, que irá tratar o evento clique do botão. Adicione o seguinte código: 126

127 DataSet dsclientes = new DataSet(); NorthwindWS.NorthwindDataProvider ndp = new NorthwindWS.NorthwindDataProvider(); dsclientes = ndp.obtercliente(txtcustomerid.text); dgvcustomer.datasource = dsclientes.tables[0]; Rode o seu programa, em CustomerId preencha ALFKI, clique no botão Buscar e verifique o resultado. Vimos assim como consumir os dados de um Web Service. Esse exemplo se encontra no CD do treinamento. Distribuindo um Web Service Para distribuir o seu Web Service para outra máquina, clique com o botão esquerdo sobre o projeto. Verifique que a barra de configurações de projeto passa a ser: Onde o botão Clique nele. efetua a função de copiar um site web de um local para outro. A janela que se abrirá permite copiar o projeto para outra localização. 127

128 Vamos criar uma duplicata do nosso WS, no diretório virtual NorthwindWS2. Na barra superior, clique em Connect. Você pode ver, no lado esquerdo, que os arquivos podem ser copiados para diversos locais. Selecione Remote Site, clique em New Web Site

129 Na janela Create New Frontpage Web, em Web URL, digite e clique OK. O Visual Studio criou, automaticamente, um novo site web vazio, com o nome dado. Agora, volte à tela anterior. Veja que agora, você já está conectado ao site: Selecione todos os arquivos e clique em para enviar os arquivos. Os arquivos selecionados serão enviados automaticamente. Agora, verifique que o novo site Northwind2 também funciona, abrindo o navegador e digitando Revisão Esperamos que, nesse ponto, você já tenha compreendido o que é um Web Service, e porque tanto se fala sobre isso. Além disso, você já deve ser capaz de criar um novo Web Service e como consumir os dados providos por um. 129

130 Capítulo 11 Depuração, Debug e Trace Objetivos Veremos nesse capítulo quais são os principais recursos disponíveis no Visual Studio 2005 para verificarmos o funcionamento de nossas aplicações desde a depuração de código, quanto log de passagem do sistema. Depurando uma aplicação A depuração de aplicações é uma ferramenta poderosa que o desenvolvedor dispõe e que usa com freqüência. Um bom desenvolvedor deve conhecer bem as funções de depuração (debug), elas são importantes para que possamos testar a lógica da aplicação, a sequência do fluxo, os valores de variáveis e objetos que vão sendo usados ao longo da execução, entre outros. Além disso, a depuração nos permite rastrear e identificar bugs reportados pela equipe de testes ou que apareceram ao longo do ciclo de vida de aplicação. O Visual Studio 2005 tem uma interface de depuração poderosa e amigável, que nos permite rastrear com rapidez o estado de variáveis e objetos, acompanhar o fluxo de execução, inspecionar a lista de chamadas, entre outros. A seguir serão descritas as funcionalidades e as telas respectivas. A maioria das telas abaixo são acessíveis apenas em modo de debug mas, se você já estiver nesse modo e mesmo assim não tiver aceso a elas, procure ativálas na opçao View no menu superior do Visual Studio. Para o exemplo, usaremos uma rotina simples que preeenche duas matrizes usando o seguinte critério: se o elemento estiver na diagonal principal (os seus índices são iguais), então ele deve conter o valor 1; 130

131 se o elemento não estiver na diagonal principal (os seus índices são iguais), o elemento deve conter a soma 0. O código está logo a seguir: public static class CalculaMatrizDiagonal /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() Matriz m = new Matriz(); int[,] diagonal = new int[3, 3]; diagonal = m.obtermatrizdiagonal(diagonal); for (int linha = 0; linha <= diagonal.getupperbound(0); linha++) for (int coluna = 0; coluna <= diagonal.getupperbound(1); coluna++) Console.Write(diagonal[linha, coluna].tostring()); Console.Write("\n"); Console.ReadLine(); public class Matriz public int[,] ObterMatrizDiagonal(int[,] matriz) for (int linha = 0; linha <= matriz.getupperbound(0); linha++) for (int coluna = 0; coluna <= matriz.getupperbound(1); coluna++) if (linha == coluna) matriz[linha, coluna] = 1; else matriz[linha, coluna] = 0; 131

132 return matriz; Breakpoints e condições Para criar um breakpoint, basta clicar na barra cinza, à esquerda do código, e é criado um breakpoint. Esse procedimento é corriqueiro e bem conhecido pelos desenvolvedores. O que é pouco usado é o recurso de se depurar usando condições, como pode ser visto na janela Breakpoints, como pode ser visto abaixo: No exemplo mostrado, a interrupção só acontecerá quando a condição (linha == 1) && (coluna == 2) for verdadeira. Para criarmos condições para breakpoints, podemos usar tanto a janela acima quanto o menu pull-down que aparece ao clicar com o botão direito sobre o breakpoint: 132

133 Watch Window A Watch Window permite adicionar expressões e variáveis, para que possamos verificar o resultado enquanto estamos debugando o nosso código. O QuickWatch A janela Quickwatch permite que inspecionemos variáveis e objetos. A grande novidade do Quickwatch na versão 2005 do Visual Studio é o Intellisense, que permite que tenhamos acesso a uma lista de propriedades e métodos quando digitamos o nome de uma classe ou objeto. Quando o elemento sendo verificado é um objeto, o Quickwatch mostra os detalhes internos em forma de árvore, o que torna muito fácil entender o funcionamento interno desse elemento. Para acessar o Quickwatch, basta apertar Ctrl+Alt+Q ou então em modo de debug clicar sobre uma variável e selecionar Quickwatch. 133

134 No exemplo a seguir, vemos uma tela do Quickwatch mostrando o objeto Me (no caso, o Form1), e abrimos a estrutura do objeto Font, aonde somos capazers de ver as propriedades internas desse objeto: A janela Output Na janela Output é mostrada a saída do console. Ali é possível ver não só o progresso da compilação, mas também todas as mensagens que são enviadas ao console como, por exemplo, System.Console.Write(). A janela Immediate A janela Immediate permite usar expressões para verificar o conteúdo das variáveis contidas no escopo. 134

135 As janelas Locals e Auto As janelas Locals e Auto tem como função mostrar as variáveis que estão dentro de um escopo. A diferença é que o escopo da janela Autos é a classe em questão, e a janela Locals mostra as variáveis que estão ou serão usadas nas três linhas anteriores e nas três linhas posteriores. Debug e Trace As classes Debug e Trace permitem escrever informações de depuração de código, para diversos tipos de saídas diferentes. No caso do Debug, as saídas serão geradas apenas quando compilamos a nossa aplicação em modo debug. Já a classe Trace envia os dados para a saída tanto no modo debug, quanto no modo release. A maior vantagem do Debug e do Trace é a possibilidade de ligar e desligar através de um ajuste no arquivo de configuração da aplicação. Ambas as classes estão contidas no namespace System.Diagnostics. Métodos do Debug e do Trace Os métodos da classe Debug e da classe Trace são estáticos, isso é, os métodos são chamados sem instanciar as classes. 135

136 São esses métodos: Write: escreve um texto e o envia para os listeners; WriteLine: o mesmo que o anterior, adicionando um símbolo de retorno ( \n ) ao final; WriteIf: escreve um texto e o envia para os listeners se a condição entrada for avaliada como True; WriteLineIf: idem, adicionando um símbolo de retorno ( \n ) ao final; Assert: escreve um texto e o envia para os listeners se a condição entrada for avaliada como False. Além disso, o Assert também faz com que esse texto seja mostrado em um MessageBox; Fail: o mesmo que Assert, mas não verifica nenhuma condição; Flush: faz com que as mensagens acumuladas no buffer sejam descarregadas na saída; AutoFlush (propriedade): faz com que, ao receber uma mensagem, o Trace ou o Debug escrevam imediatamente para a saída; Indent e Unindent: aumentam ou diminuem o nível de identação da saída, trazendo melhor legibilidade para o texto. Listeners Ambas as classes (Debug e Trace) escrevem para uma mesma coleção de saídas (chamada coleção de Listeners). Por padrão, essa coleção já vem com um listener, que aponta para a janela de Console da aplicação. Entretanto, é possível adicionar novas saídas (listeners). Vamos ver como adicionar um listener que grava as mensagens em um arquivo texto. Para isso, vamos alterar o exemplo, para ao invés dele escrever no Command prompt com o Console.Write, ele escrever no Trace: Matriz m = new Matriz(); int[,] diagonal = new int[3, 3]; diagonal = m.obtermatrizdiagonal(diagonal); 136

137 System.IO.FileStream fs = new System.IO.FileStream("c:\\teste.txt", System.IO.FileMode.OpenOrCreate); TextWriterTraceListener filelistener = new TextWriterTraceListener(fs); Trace.Listeners.Add(fileListener); Trace.AutoFlush = true; for (int linha = 0; linha <= diagonal.getupperbound(0); linha++) for (int coluna = 0; coluna <= diagonal.getupperbound(1); coluna++) Trace.Write(diagonal[linha, coluna].tostring()); Trace.Write("\r\n"); Revisão Vimos as principais janelas utilizadas na depuração de nosso código, como inserir breakpoint e breakpoints condicionais, e como gerar um log do funcionamento de nossa aplicação através das classes Debug e Trace. 137

138 Capítulo 12 Distribuição Objetivos Agora que a nossa aplicação está funcionando corretamente, precisamos distribuir nossa aplicação para a máquina dos clientes. Veremos nesse capítulo como distribuir nossas aplicações: como criar um projeto de setup, como personalizá-lo e como configurá-lo para distribuir corretamente a sua solução, como usar a distribuição no formato Click-Once; e como gerar pacotes de atualização. Tipos de setup suportados O Visual Studio permite que sejam criados os seguintes tipos de projeto: Setup Project, usado para construir instaladores de aplicativos Windows, gera arquivos.msi e.exe, sendo o arquivo.msi o instalador, e o.exe ; Merge Module Project, usado para construir pacotes de componentes, gerando arquivos com extensão.msm Cab Project, usado para construir arquivos.cab para distribuir componentes ActiveX que rodam em browser; Web Setup Project: usado para construir instaladores de aplicações Web; Setup Wizard: assistente para criar os projetos de setup acima; Smart Device CAB Project: usado para criar instaladores para dispositivos móveis. Criando um projeto de setup Para criar um projeto de setup, é possível fazê-lo dentro da mesma Solution ou criar uma Solution nova. Nesse exemplo, mostraremos como criar um projeto de setup na mesma Solution, embora criar uma nova Solution tenham passos similares. 138

139 Para começarmos, crie um novo projeto, escolha Other Project Types, Setup and Deployment, e escolha Setup Wizard. Você pode também mudar o nome e o diretório do projeto: Na tela seguinte, escolhemos o tipo de setup: Na próxima tela escolhemos o que deve ser incluso no instalador: 139

140 Uma das grandes vantagens de se criar um projeto de setup na mesma Solution em que se encontra a aplicação é que a lista acima aparece, permitindo selecionarmos para cada projeto os grupos de arquivos que queremos incluir no setup (note que, no exemplo, temos os arquivos do projeto AdoptionLab1 e, logo abaixo, do projeto ConsumidorWS, repetindo as opcões para todos os projetos da mesma Solution). As opções são: Localized resources: dlls e recursos de localização do aplicativo; XML serialization Assemblies: caso existam assemblies serializados; Content Files: arquivos internos do projeto; Primary output: os assemblies que são compilados quando se faz Build do projeto. Essa é a opção mais usada; Source files: caso se deseje incluir o código-fonte do aplicativo no instalador; Debug symbols: para incluir os debug symbols, que auxiliam programadores avançados e o prórpio Visial Studio a debugarem a aplicação sem necessariamente ter o código-fonte; 140

141 Documentation files: arquivos de documentação gerados pelo Visual Studio. A tela seguinte permite incluir outros arquivos, como por exemplo arquivos de Help, arquivos readme.txt e outros que não são diretamente gerenciados pelo Visual Studio: A próxima tela confirma as opções escolhidas e encerra o assistente, criando mais um projeto no Solution. Personalizando o setup 141

142 Nas propriedades do projeto de Setup estão os primeiros itens configuráveis. Os que mais são usados são: Manufacturer: nome da empresa, pode ser usada para montar o caminho (path) de instalação; ProductCode, UpgradeCode, Version: vistos mais à frente; Localization: configurações regionais do instalador, incluindo não só a formatação de números, mas também a língua em que serão mostradas as mensagens. Para as telas padrão (veja ainda nesse capítulo detalhes das telas de setup), as mensagens estão disponíveis em vários idiomas, inclusive o Português. O projeto de setup tem diversas opções que pode ser customizadas. A maioria é acessível ao se clicar no projeto com o botão direito e escolher View: 142

143 Seção File System Na seção File System podemos incluir, excluir e alterar os arquivos que serão inclusos no nosso instalador. Tembém é nessa seção que podemos alterar o caminho (path) padrão em que o programa será instalado, como veremos a seguir. Note que a maioria dos itens possui páginas de propriedades, como a mostrada na figura. Nas propriedades de Application Folder, temos uma configuração importante: o caminho default de instalação da aplicação, na propriedade DefaultLocation. Em Application Folder, colocamos todos os arquivos e pastas que serão criados no diretório da aplicação. Para adicionar arquivos, clique com o botão direito em Application Folder e clique em Add. 143

144 Em User s Desktop ficam os ícones e as pastas que queremos que o instalador adicione à Área de Trabalho do usuário. Em User s Program Menu ficam os ícones que serão colocados na pasta Programas no menu Iniciar. A cada opção, podemos ver a página de propriedades e notar configurações importantes, como o bitmap de um ícone ou a opção de resgitro de um componente COM. Seção Registry Na seção Registry, é possível configurar para que o instalador crie chaves de registro na instalação. Seção File Types Na seção File Types fazemos o mapeamento de extensões para as aplicações. Essa opção pode fazer com que, por exemplo, arquivos de um certo tipo sejam abertas com uma de suas aplicações. O instalador do Office, por exemplo, cria mapeamentos de arquivos.xls para serem abertos com o Excel.exe e arquivos.doc sejam abertos com o Winword.exe. 144

145 Seção User Interface Nessa seção é possível configurar, editar e adicionar as telas do instalador: Note no detalhe que, nas propriedades, podemos alterar o conteúdo da mensagem. Sempre que houver mudança de mensagem, o instalador aceitará como válida a mensagem inserida nessa tela de propriedades, e desprezará a mensagem do arquivo de linguagem respectivo, conforme selecionado nas propriedades do projeto. Há também a possibilidade de incluir novas telas a partir de templates prontos (não é possível customizá-las além do que o Visual Studio oferece) e, inclusive, capturar nessas telas variáveis que serão usadas como condições do instalador. Consulte a documentação para ver mais detalhes. Seções Custom Actions e Launch Conditions A seção Custom Actions permite que sejam chamados scripts, classes ou métodos estáticos dentro de assemblies. Isso é usado para, por exemplo, fazer o registro de uma versão full do aplicativo através do setup. 145

146 Na última opção, Launch Conditions, é possível condicionar a instalação à presença de certos arquivos, chaves de registro ou instalador (opção Search Target Machine) e também condições do instalador, como a presença do framework 2.0 (opção default do instalador) e outras condições, como a verificação de um arquivo ou uma chave criada em uma das telas customizadas do projeto de setup. Criando um projeto de atualização Uma dúvida recorrente e que mereceu tópico separado é o projeto de atualização. A sua configuração é simples e é feita nas propriedades do projeto: Para fazer com que o projeto de instalação reconheça que é uma nova versão, basta atualizar a propriedade Version. Uma janela perguntará se você deseja atualizar o código da versão, basta clicar em Yes e o seu GUID será atualizado. Note também a opção RemovePreviousVersions, que poderá ser alterada caso você deseje que o instalador, na atualização, remova as versões anteriores. 146

147 Click-once deploy Note que ao clicar com o botão direito em qualquer um dos projetos do tipo WindowsApplication, há a opção Publish. Essa opção nos permite publicar um instalador simples que pode ser rapidamente publicado em um servidor Web para download ou atualização. Para acessar o ClickOnce o click-once, basta selecionar Publish... e o assistente do ClickOnce entrará em ação. Primeiro precisaremos escolher aonde serão disponibilizados os arquivos de deistribuição: Depois escolhemos o tipo da aplicação: 147

148 A primeira opção nos permite criar um instalador que criará atalhos no menu Iniciar e permitirá que a aplicação seja desinstalada através na opção Adicionar/Remover Programas, que pode ser acessada pelo painel de controle. A segunda opção nos permite criar um instalador mais simples, que apenas faz com que a aplicação execute. Entretanto, o usuário tem sempre que acessá-la através de rede, fazendo o seu download sempre que dela precisar. Na última tela, confirmamos as opções escolhidas e, ao clicar em Finish, o ClickOnce começa a trabalhar. Ao final, o Visual Studio chama um novo browser e já mostra uma página-modelo para fazer download da aplicação: 148

Treinar - Cursos e Treinamentos C# Módulo I. Carga horária: 32 Horas

Treinar - Cursos e Treinamentos C# Módulo I. Carga horária: 32 Horas Treinar - Cursos e Treinamentos C# Módulo I Carga horária: 32 Horas Pré-requisito: Para que os alunos possam aproveitar este treinamento ao máximo, é importante que eles tenham participado dos treinamentos

Leia mais

Framework.NET, Microsoft Visual C# 2010 Express e Elementos da Linguagem C#

Framework.NET, Microsoft Visual C# 2010 Express e Elementos da Linguagem C# Linguagem de Programação 3 Framework.NET, Microsoft Visual C# 2010 Express e Elementos da Linguagem C# Prof. Mauro Lopes 1-31 35 Objetivos Nesta aula iremos apresentar a tecnologia.net, o ambiente de desenvolvimento

Leia mais

Orientação a Objetos

Orientação a Objetos 1. Domínio e Aplicação Orientação a Objetos Um domínio é composto pelas entidades, informações e processos relacionados a um determinado contexto. Uma aplicação pode ser desenvolvida para automatizar ou

Leia mais

Fundament n os s da platafo f rm r a. NE N T André Menegassi

Fundament n os s da platafo f rm r a. NE N T André Menegassi Fundamentos da plataforma.net André Menegassi O que é o.net Framework?.NET é uma plataforma de software para desenvolvimento de aplicações que conecta informações, sistemas, pessoas e dispositivos através

Leia mais

Linguagem de Programação Procedural (VB) Prof. MSc Eng Marcelo Bianchi AULA 01 - INTRODUÇÃO AO VB

Linguagem de Programação Procedural (VB) Prof. MSc Eng Marcelo Bianchi AULA 01 - INTRODUÇÃO AO VB Linguagem de Programação Procedural (VB) Prof. MSc Eng Marcelo Bianchi AULA 01 - INTRODUÇÃO AO VB Visão Geral do Visual Basic.NET Conceitos Básicos Antes de codificar um programa dentro do Visual Studio

Leia mais

DESENVOLVIMENTO DE SOFTWARE AULA 1

DESENVOLVIMENTO DE SOFTWARE AULA 1 DESENVOLVIMENTO DE SOFTWARE AULA 1 CAMPUS SANTO ANDRÉ CELSO CANDIDO SEMESTRE 2014 1 Características da Plataforma.NET A plataforma.net Framework 4.0 (.NET 4.0) é uma plataforma de softwares que fornece

Leia mais

PADI 2015/16. Aula 1 Introdução à Plataforma.NET

PADI 2015/16. Aula 1 Introdução à Plataforma.NET PADI 2015/16 Aula 1 Introdução à Plataforma.NET 1 Sumário 1. Framework.NET Arquitectura 2. Linguagem C# 2.0 Sintaxe C# vs. Java vs. C++ 3. IDE: MS Visual Studio 2005 ou superior Ferramentas Console/Win

Leia mais

Prof. Esp. Adriano Carvalho

Prof. Esp. Adriano Carvalho Prof. Esp. Adriano Carvalho O que é um Programa? Um arquivo contendo uma sequência de comandos em uma linguagem de programação especifica Esses comandosrespeitam regras de como serem escritos e quais

Leia mais

A interface do Microsoft Visual Studio 2005

A interface do Microsoft Visual Studio 2005 Tarefa Orientada 1 A interface do Microsoft Visual Studio 2005 Objectivos: Introdução à framework.net Iniciar o Visual Studio 2005. Criar um novo projecto de Windows Forms em Visual Basic Introdução à

Leia mais

2 Orientação a objetos na prática

2 Orientação a objetos na prática 2 Orientação a objetos na prática Aula 04 Sumário Capítulo 1 Introdução e conceitos básicos 1.4 Orientação a Objetos 1.4.1 Classe 1.4.2 Objetos 1.4.3 Métodos e atributos 1.4.4 Encapsulamento 1.4.5 Métodos

Leia mais

Seminário - C# DSO II. Desenvolvimento de Sistemas Orientados a Objetos 2. Equipe: Diorges, Leonardo, Luís Fernando, Ronaldo

Seminário - C# DSO II. Desenvolvimento de Sistemas Orientados a Objetos 2. Equipe: Diorges, Leonardo, Luís Fernando, Ronaldo Seminário - C# DSO II Desenvolvimento de Sistemas Orientados a Objetos 2 Equipe: Diorges, Leonardo, Luís Fernando, Ronaldo Roteiro Breve Histórico Plataforma.NET Características da Linguagem Sintaxe Versões

Leia mais

Algoritmos e Programação Estruturada

Algoritmos e Programação Estruturada Algoritmos e Programação Estruturada Virgínia M. Cardoso Linguagem C Criada por Dennis M. Ritchie e Ken Thompson no Laboratório Bell em 1972. A Linguagem C foi baseada na Linguagem B criada por Thompson.

Leia mais

Programação de Computadores - I. Profª Beatriz Profº Israel

Programação de Computadores - I. Profª Beatriz Profº Israel Programação de Computadores - I Profª Beatriz Profº Israel Ambiente de Desenvolvimento Orientação a Objetos É uma técnica de desenvolvimento de softwares que consiste em representar os elementos do mundo

Leia mais

Programando em C# Orientado a Objetos. By: Maromo

Programando em C# Orientado a Objetos. By: Maromo Programando em C# Orientado a Objetos By: Maromo Agenda Módulo 1 Plataforma.Net. Linguagem de Programação C#. Tipos primitivos, comandos de controle. Exercícios de Fixação. Introdução O modelo de programação

Leia mais

CURSO DE PROGRAMAÇÃO EM JAVA

CURSO DE PROGRAMAÇÃO EM JAVA CURSO DE PROGRAMAÇÃO EM JAVA Introdução para Iniciantes Prof. M.Sc. Daniel Calife Índice 1 - A programação e a Linguagem Java. 1.1 1.2 1.3 1.4 Linguagens de Programação Java JDK IDE 2 - Criando o primeiro

Leia mais

Introdução ao C# . Visão geral do.net Framework

Introdução ao C# . Visão geral do.net Framework Introdução ao C# Microsoft.NET (comumente conhecido por.net Framework - em inglês: dotnet) é uma iniciativa da empresa Microsoft, que visa uma plataforma única para desenvolvimento e execução de sistemas

Leia mais

Memória Flash. PdP. Autor: Tiago Lone Nível: Básico Criação: 11/12/2005 Última versão: 18/12/2006. Pesquisa e Desenvolvimento de Produtos

Memória Flash. PdP. Autor: Tiago Lone Nível: Básico Criação: 11/12/2005 Última versão: 18/12/2006. Pesquisa e Desenvolvimento de Produtos TUTORIAL Memória Flash Autor: Tiago Lone Nível: Básico Criação: 11/12/2005 Última versão: 18/12/2006 PdP Pesquisa e Desenvolvimento de Produtos http://www.maxwellbohr.com.br contato@maxwellbohr.com.br

Leia mais

Google Drive. Passos. Configurando o Google Drive

Google Drive. Passos. Configurando o Google Drive Google Drive um sistema de armazenagem de arquivos ligado à sua conta Google e acessível via Internet, desta forma você pode acessar seus arquivos a partir de qualquer dispositivo que tenha acesso à Internet.

Leia mais

Barra de ferramentas padrão. Barra de formatação. Barra de desenho Painel de Tarefas

Barra de ferramentas padrão. Barra de formatação. Barra de desenho Painel de Tarefas Microsoft Power Point 2003 No Microsoft PowerPoint 2003, você cria sua apresentação usando apenas um arquivo, ele contém tudo o que você precisa uma estrutura para sua apresentação, os slides, o material

Leia mais

ARRAYS. Um array é um OBJETO que referencia (aponta) mais de um objeto ou armazena mais de um dado primitivo.

ARRAYS. Um array é um OBJETO que referencia (aponta) mais de um objeto ou armazena mais de um dado primitivo. Cursos: Análise, Ciência da Computação e Sistemas de Informação Programação I - Prof. Aníbal Notas de aula 8 ARRAYS Introdução Até agora, utilizamos variáveis individuais. Significa que uma variável objeto

Leia mais

Veja abaixo um exemplo de como os dados são mostrados quando usamos o

Veja abaixo um exemplo de como os dados são mostrados quando usamos o Objeto DataGridView O controle DataGridView é um dos objetos utilizados para exibir dados de tabelas de um banco de dados. Ele está disponível na guia de objetos Data na janela de objetos do vb.net. Será

Leia mais

LP II Estrutura de Dados. Introdução e Linguagem C. Prof. José Honorato F. Nunes honorato.nunes@ifbaiano.bonfim.edu.br

LP II Estrutura de Dados. Introdução e Linguagem C. Prof. José Honorato F. Nunes honorato.nunes@ifbaiano.bonfim.edu.br LP II Estrutura de Dados Introdução e Linguagem C Prof. José Honorato F. Nunes honorato.nunes@ifbaiano.bonfim.edu.br Resumo da aula Considerações Gerais Introdução a Linguagem C Variáveis e C Tipos de

Leia mais

Arquivos de Textos no C - Básico

Arquivos de Textos no C - Básico OpenStax-CNX module: m47676 1 Arquivos de Textos no C - Básico Joao Carlos Ferreira dos Santos This work is produced by OpenStax-CNX and licensed under the Creative Commons Attribution License 3.0 TRABALHANDO

Leia mais

ANDRÉ APARECIDO DA SILVA APOSTILA BÁSICA SOBRE O POWERPOINT 2007

ANDRÉ APARECIDO DA SILVA APOSTILA BÁSICA SOBRE O POWERPOINT 2007 ANDRÉ APARECIDO DA SILVA APOSTILA BÁSICA SOBRE O POWERPOINT 2007 CURITIBA 2015 2 SUMÁRIO INTRODUÇÃO AO MICROSOFT POWERPOINT 2007... 3 JANELA PRINCIPAL... 3 1 - BOTÃO OFFICE... 4 2 - FERRAMENTAS DE ACESSO

Leia mais

Esta dissertação apresentou duas abordagens para integração entre a linguagem Lua e o Common Language Runtime. O objetivo principal da integração foi

Esta dissertação apresentou duas abordagens para integração entre a linguagem Lua e o Common Language Runtime. O objetivo principal da integração foi 5 Conclusão Esta dissertação apresentou duas abordagens para integração entre a linguagem Lua e o Common Language Runtime. O objetivo principal da integração foi permitir que scripts Lua instanciem e usem

Leia mais

AMBIENTE. FORMULÁRIO: é a janela do aplicativo apresentada ao usuário. Considere o formulário como a sua prancheta de trabalho.

AMBIENTE. FORMULÁRIO: é a janela do aplicativo apresentada ao usuário. Considere o formulário como a sua prancheta de trabalho. DELPHI BÁSICO VANTAGENS Ambiente de desenvolvimento fácil de usar; 1. Grande Biblioteca de Componentes Visuais (VCL - Visual Component Library), que são botões, campos, gráficos, caixas de diálogo e acesso

Leia mais

2 echo "PHP e outros.";

2 echo PHP e outros.; PHP (Hypertext Preprocessor) Antes de qualquer coisa, precisamos entender o que é o PHP: O PHP(Hypertext Preprocessor) é uma linguagem interpretada gratuita, usada originalmente apenas para o desenvolvimento

Leia mais

Programação Estruturada e Orientada a Objetos. Fundamentos Orientação a Objetos

Programação Estruturada e Orientada a Objetos. Fundamentos Orientação a Objetos Programação Estruturada e Orientada a Objetos Fundamentos Orientação a Objetos 2013 O que veremos hoje? Introdução aos fundamentos de Orientação a Objetos Transparências baseadas no material do Prof. Jailton

Leia mais

NetBeans. Conhecendo um pouco da IDE

NetBeans. Conhecendo um pouco da IDE NetBeans Conhecendo um pouco da IDE Professor: Edwar Saliba Júnior Sumário Apresentação:...1 Criando Um Novo Projeto de Software:...1 Depurando Um Código-fonte:...4 Entendendo o Código-fonte:...7 Dica

Leia mais

SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2

SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2 SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2 1.1 Introdução... 2 1.2 Estrutura do IP... 3 1.3 Tipos de IP... 3 1.4 Classes de IP... 4 1.5 Máscara de Sub-Rede... 6 1.6 Atribuindo um IP ao computador... 7 2

Leia mais

Google Drive: Acesse e organize seus arquivos

Google Drive: Acesse e organize seus arquivos Google Drive: Acesse e organize seus arquivos Use o Google Drive para armazenar e acessar arquivos, pastas e documentos do Google Docs onde quer que você esteja. Quando você altera um arquivo na web, no

Leia mais

O Primeiro Programa em Visual Studio.net

O Primeiro Programa em Visual Studio.net O Primeiro Programa em Visual Studio.net Já examinamos o primeiro programa escrito em C que servirá de ponto de partida para todos os demais exemplos e exercícios do curso. Agora, aprenderemos como utilizar

Leia mais

Microsoft Office PowerPoint 2007

Microsoft Office PowerPoint 2007 INTRODUÇÃO AO MICROSOFT POWERPOINT 2007 O Microsoft Office PowerPoint 2007 é um programa destinado à criação de apresentação através de Slides. A apresentação é um conjunto de Sides que são exibidos em

Leia mais

Java. Marcio de Carvalho Victorino www.dominandoti.eng.br

Java. Marcio de Carvalho Victorino www.dominandoti.eng.br Java Marcio de Carvalho Victorino www.dominandoti.eng.br 3. Considere as instruções Java abaixo: int cont1 = 3; int cont2 = 2; int cont3 = 1; cont1 += cont3++; cont1 -= --cont2; cont3 = cont2++; Após a

Leia mais

Android e Bancos de Dados

Android e Bancos de Dados (Usando o SQLite) Programação de Dispositivos Móveis Mauro Lopes Carvalho Silva Professor EBTT DAI Departamento de Informática Campus Monte Castelo Instituto Federal de Educação Ciência e Tecnologia do

Leia mais

ECD1200 Equipamento de Consulta de Dados KIT DE DESENVOLVIMENTO

ECD1200 Equipamento de Consulta de Dados KIT DE DESENVOLVIMENTO Equipamento de Consulta de Dados KIT DE DESENVOLVIMENTO Versão do documento: 1.1 1. Introdução...3 2. Documentação...3 2.1. DOCUMENTAÇÃO DE REFERÊNCIA... 3 2.2. DESCRIÇÃO FUNCIONAL... 4 2.2.1. INTERFACE...

Leia mais

Prática 6 ActionScript

Prática 6 ActionScript Prática 6 ActionScript 1. Objetivos Se familiarizar com o ActionScript. Usar comandos e funções básicas. 2. Recursos Necessários Computador com o programa Macromedia Flash MX ou superior. 3. Conceitos

Leia mais

Criando & Consumindo um WebService com ASP.NET 2.0 Publicado em: 25 de Agosto de 2007 Por Herman Ferdinando Arais

Criando & Consumindo um WebService com ASP.NET 2.0 Publicado em: 25 de Agosto de 2007 Por Herman Ferdinando Arais ASP.NET > WebService herman_arais@yahoo.com.br Introdução Um WebService é um componente, ou unidade lógica de aplicação, acessível através de protocolos padrões de Internet. Como componentes, esses serviços

Leia mais

Bem- Vindo ao manual de instruções do ECO Editor de COnteúdo.

Bem- Vindo ao manual de instruções do ECO Editor de COnteúdo. Manual de Instruções ECO Editor de Conteúdo Bem- Vindo ao manual de instruções do ECO Editor de COnteúdo. O ECO é um sistema amigável e intui?vo, mas abaixo você pode?rar eventuais dúvidas e aproveitar

Leia mais

Fluxo de trabalho do Capture Pro Software: Indexação de OCR e separação de documentos de código de correção

Fluxo de trabalho do Capture Pro Software: Indexação de OCR e separação de documentos de código de correção Este procedimento corresponde ao fluxo de trabalho de Indexação de OCR com separação de código de correção no programa de treinamento do Capture Pro Software. As etapas do procedimento encontram-se na

Leia mais

Análise e Desenvolvimento de Sistemas ADS Programação Orientada a Obejeto POO 3º Semestre AULA 03 - INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETO (POO)

Análise e Desenvolvimento de Sistemas ADS Programação Orientada a Obejeto POO 3º Semestre AULA 03 - INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETO (POO) Análise e Desenvolvimento de Sistemas ADS Programação Orientada a Obejeto POO 3º Semestre AULA 03 - INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETO (POO) Parte: 1 Prof. Cristóvão Cunha Objetivos de aprendizagem

Leia mais

Introdução a listas - Windows SharePoint Services - Microsoft Office Online

Introdução a listas - Windows SharePoint Services - Microsoft Office Online Page 1 of 5 Windows SharePoint Services Introdução a listas Ocultar tudo Uma lista é um conjunto de informações que você compartilha com membros da equipe. Por exemplo, você pode criar uma folha de inscrição

Leia mais

Profº. Enrique Pimentel Leite de Oliveira

Profº. Enrique Pimentel Leite de Oliveira Profº. Enrique Pimentel Leite de Oliveira O termo orientação a objetos significa organizar o mundo real como uma coleção de objetos que incorporam estrutura de dados e um conjunto de operações que manipulam

Leia mais

Introdução à Programação

Introdução à Programação Introdução à Programação Introdução a Linguagem C Construções Básicas Programa em C #include int main ( ) { Palavras Reservadas } float celsius ; float farenheit ; celsius = 30; farenheit = 9.0/5

Leia mais

Manual AGENDA DE BACKUP

Manual AGENDA DE BACKUP Gemelo Backup Online DESKTOP Manual AGENDA DE BACKUP Realiza seus backups de maneira automática. Você só programa os dias e horas em que serão efetuados. A única coisa que você deve fazer é manter seu

Leia mais

Display de 7. PdP. Autor: Tiago Lone Nível: Básico Criação: 16/12/2005 Última versão: 18/12/2006. Pesquisa e Desenvolvimento de Produtos

Display de 7. PdP. Autor: Tiago Lone Nível: Básico Criação: 16/12/2005 Última versão: 18/12/2006. Pesquisa e Desenvolvimento de Produtos TUTORIAL Display de 7 Segmentos Autor: Tiago Lone Nível: Básico Criação: 16/12/2005 Última versão: 18/12/2006 PdP Pesquisa e Desenvolvimento de Produtos http://www.maxwellbohr.com.br contato@maxwellbohr.com.br

Leia mais

Ambientes Visuais. Ambientes Visuais

Ambientes Visuais. Ambientes Visuais Ambientes Visuais Inicialmente, apenas especialistas utilizavam os computadores, sendo que os primeiros desenvolvidos ocupavam grandes áreas e tinham um poder de processamento reduzido. Porém, a contínua

Leia mais

Linguagens de. Aula 02. Profa Cristiane Koehler cristiane.koehler@canoas.ifrs.edu.br

Linguagens de. Aula 02. Profa Cristiane Koehler cristiane.koehler@canoas.ifrs.edu.br Linguagens de Programação III Aula 02 Profa Cristiane Koehler cristiane.koehler@canoas.ifrs.edu.br Linguagens de Programação Técnica de comunicação padronizada para enviar instruções a um computador. Assim

Leia mais

Curso de Java. Orientação a objetos e a Linguagem JAVA. TodososdireitosreservadosKlais

Curso de Java. Orientação a objetos e a Linguagem JAVA. TodososdireitosreservadosKlais Curso de Java Orientação a objetos e a Linguagem JAVA Roteiro A linguagem Java e a máquina virtual Objetos e Classes Encapsulamento, Herança e Polimorfismo Primeiro Exemplo A Linguagem JAVA Principais

Leia mais

Trecho retirando do Manual do esocial Versão 1.1

Trecho retirando do Manual do esocial Versão 1.1 Trecho retirando do Manual do esocial Versão 1.1 A rotina de acesso direto ao XML do S-1000, o usuário pode encontrar na opção de cadastro de Empresas do SIP. Sempre que o usuário localizar a figura ao

Leia mais

Instalando o Internet Information Services no Windows XP

Instalando o Internet Information Services no Windows XP Internet Information Services - IIS Se você migrou recentemente do Windows 95 ou 98 para o novo sitema operacional da Microsoft Windows XP, e utilizava antes o Personal Web Server, deve ter notado que

Leia mais

3. No painel da direita, dê um clique com o botão direito do mouse em qualquer espaço livre (área em branco).

3. No painel da direita, dê um clique com o botão direito do mouse em qualquer espaço livre (área em branco). Permissões de compartilhamento e NTFS - Parte 2 Criando e compartilhando uma pasta - Prática Autor: Júlio Battisti - Site: www.juliobattisti.com.br Neste tópico vamos criar e compartilhar uma pasta chamada

Leia mais

Programação para Dispositivos Móveis Aula 1. Prof. William Yamamoto

Programação para Dispositivos Móveis Aula 1. Prof. William Yamamoto Programação para Dispositivos Móveis Aula 1 Prof. William Yamamoto Visual Studio É uma ferramenta de desenvolvimento completa que atende praticamente a todas as plataformas de desenvolvimento, como: Web

Leia mais

Dicas para usar melhor o Word 2007

Dicas para usar melhor o Word 2007 Dicas para usar melhor o Word 2007 Quem está acostumado (ou não) a trabalhar com o Word, não costuma ter todo o tempo do mundo disponível para descobrir as funcionalidades de versões recentemente lançadas.

Leia mais

DarkStat para BrazilFW

DarkStat para BrazilFW DarkStat para BrazilFW ÍNDICE Índice Página 1 O que é o DarkStat Página 2 DarkStat e a inicialização do sistema Página 2 DarkStat e a finalização do sistema Página 2 Tela Principal do DarkStat Página 3

Leia mais

02 - Usando o SiteMaster - Informações importantes

02 - Usando o SiteMaster - Informações importantes 01 - Apresentação do SiteMaster - News Edition O SiteMaster foi desenvolvido para ser um sistema simples de gerenciamento de notícias, instalado em seu próprio computador e com configuração simplificada,

Leia mais

Microsoft Access XP Módulo Um

Microsoft Access XP Módulo Um Microsoft Access XP Módulo Um Neste primeiro módulo de aula do curso completo de Access XP vamos nos dedicar ao estudo de alguns termos relacionados com banco de dados e as principais novidades do novo

Leia mais

Questão - 01. Essência do Excel 2003...

Questão - 01. Essência do Excel 2003... Valdir Questão - 01 Como deve proceder o usuário do Microsoft para que sejam atualizados os cálculos das funções ou fórmulas utilizadas nas planilhas? a) Pressionar a tecla F9 no teclado b) Pressionar

Leia mais

Resumo da Matéria de Linguagem de Programação. Linguagem C

Resumo da Matéria de Linguagem de Programação. Linguagem C Resumo da Matéria de Linguagem de Programação Linguagem C Vitor H. Migoto de Gouvêa 2011 Sumário Como instalar um programa para executar o C...3 Sintaxe inicial da Linguagem de Programação C...4 Variáveis

Leia mais

AULA 4 VISÃO BÁSICA DE CLASSES EM PHP

AULA 4 VISÃO BÁSICA DE CLASSES EM PHP AULA 4 VISÃO BÁSICA DE CLASSES EM PHP Antes de mais nada, vamos conhecer alguns conceitos, que serão importantes para o entendimento mais efetivos dos assuntos que trataremos durante a leitura desta apostila.

Leia mais

Fluxo de trabalho do Capture Pro Software: Indexação de código de barras e separação de documentos

Fluxo de trabalho do Capture Pro Software: Indexação de código de barras e separação de documentos Este procedimento corresponde ao fluxo de trabalho de Indexação de código de barras e de separação de documentos no programa de treinamento do Capture Pro Software. As etapas do procedimento encontram-se

Leia mais

Aprenda as melhores práticas para construir um completo sistema de teste automatizado

Aprenda as melhores práticas para construir um completo sistema de teste automatizado Aprenda as melhores práticas para construir um completo sistema de teste automatizado Renan Azevedo Engenheiro de Produto de Teste e Medição -Américas Aprenda as melhores práticas para construir um completo

Leia mais

Procedimentos para Reinstalação do Sisloc

Procedimentos para Reinstalação do Sisloc Procedimentos para Reinstalação do Sisloc Sumário: 1. Informações Gerais... 3 2. Criação de backups importantes... 3 3. Reinstalação do Sisloc... 4 Passo a passo... 4 4. Instalação da base de dados Sisloc...

Leia mais

Iniciação à Informática

Iniciação à Informática Meu computador e Windows Explorer Justificativa Toda informação ou dado trabalhado no computador, quando armazenado em uma unidade de disco, transforma-se em um arquivo. Saber manipular os arquivos através

Leia mais

Desenvolvendo Websites com PHP

Desenvolvendo Websites com PHP Desenvolvendo Websites com PHP Aprenda a criar Websites dinâmicos e interativos com PHP e bancos de dados Juliano Niederauer 19 Capítulo 1 O que é o PHP? O PHP é uma das linguagens mais utilizadas na Web.

Leia mais

Lógica de Programação

Lógica de Programação Lógica de Programação Unidade 4 Ambiente de desenvolvimento Java QI ESCOLAS E FACULDADES Curso Técnico em Informática SUMÁRIO A LINGUAGEM JAVA... 3 JVM, JRE, JDK... 3 BYTECODE... 3 PREPARANDO O AMBIENTE

Leia mais

Microsoft Visual Studio 2010 C# Volume II

Microsoft Visual Studio 2010 C# Volume II Microsoft Visual Studio 2010 C# Volume II Apostila desenvolvida pelos Professores Ricardo Santos de Jesus e Rovilson de Freitas, para as Disciplinas de Desenvolvimento de Software I e II, nas Etecs de

Leia mais

1. Apresentação. 1.1. Objetivos

1. Apresentação. 1.1. Objetivos 1.1. Objetivos 1. Apresentação Neste capítulo estão descritos os objetivos gerais do livro, os requisitos desejáveis do estudante para que possa utilizá-lo eficientemente, e os recursos necessários em

Leia mais

PROGRAMANDO EM C# ORIENTADO A OBJETOS

PROGRAMANDO EM C# ORIENTADO A OBJETOS PROGRAMANDO EM C# ORIENTADO A OBJETOS AGENDA MÓDULO 4 IDE Visual Studio e edições Exemplos IDE - INTEGRATED DEVELOPMENT ENVIRONMENT IDE, Ambiente de Desenvolvimento Integrado. Uma IDE é uma ferramenta

Leia mais

Conhecendo o Visual FoxPro 8.0 Parte 1

Conhecendo o Visual FoxPro 8.0 Parte 1 AULA Conhecendo o Visual FoxPro 8.0 Parte 1 Em qualquer profissão é importante que se conheça bem as ferramentas que serão usadas para executar o trabalho proposto. No desenvolvimento de software não é

Leia mais

Trabalhando com conexão ao banco de dados MySQL no Lazarus. Prof. Vitor H. Migoto de Gouvêa Colégio IDESA 2011

Trabalhando com conexão ao banco de dados MySQL no Lazarus. Prof. Vitor H. Migoto de Gouvêa Colégio IDESA 2011 Trabalhando com conexão ao banco de dados MySQL no Lazarus Prof. Vitor H. Migoto de Gouvêa Colégio IDESA 2011 Edição 4 O Componente Trabalhando com conexão ao banco de dados MySQL no Lazarus Ano: 03/2011

Leia mais

Pesquisa e organização de informação

Pesquisa e organização de informação Pesquisa e organização de informação Capítulo 3 A capacidade e a variedade de dispositivos de armazenamento que qualquer computador atual possui, tornam a pesquisa de informação um desafio cada vez maior

Leia mais

ÍNDICE... 2 INTRODUÇÃO... 4

ÍNDICE... 2 INTRODUÇÃO... 4 Mic crosoft Excel 201 0 ÍNDICE ÍNDICE... 2 INTRODUÇÃO... 4 Interface... 4 Guias de Planilha... 5 Movimentação na planilha... 6 Entrada de textos e números... 7 Congelando painéis... 8 Comentários nas Células...

Leia mais

Componentes da linguagem C++

Componentes da linguagem C++ Componentes da linguagem C++ C++ é uma linguagem de programação orientada a objetos (OO) que oferece suporte às características OO, além de permitir você realizar outras tarefas, similarmente a outras

Leia mais

Persistência de Dados

Persistência de Dados Persistência de s Universidade do Estado de Santa Catarina - Udesc Centro de Ciências Tecnológicas - CCT Departamento de Ciência da Computação Tecnologia de Sistemas de Informação Estrutura de s II - DAD

Leia mais

APOSTILA DE EXEMPLO. (Esta é só uma reprodução parcial do conteúdo)

APOSTILA DE EXEMPLO. (Esta é só uma reprodução parcial do conteúdo) APOSTILA DE EXEMPLO (Esta é só uma reprodução parcial do conteúdo) 1 Índice Aula 1 - Área de trabalho e personalizando o sistema... 3 A área de trabalho... 3 Partes da área de trabalho.... 4 O Menu Iniciar:...

Leia mais

MANUAL DE UTILIZAÇÃO SISTEMA DE CADASTRO INTRANET

MANUAL DE UTILIZAÇÃO SISTEMA DE CADASTRO INTRANET MANUAL DE UTILIZAÇÃO SISTEMA DE CADASTRO INTRANET I Sumário 1. Objetivo do Documento... 1 2. Início... 1 3. Cadastro de Pessoa Física... 3 3.1. Preenchimentos Obrigatórios.... 4 3.2. Acesso aos Campos

Leia mais

Prof. Esp. Adriano Carvalho

Prof. Esp. Adriano Carvalho Prof. Esp. Adriano Carvalho Um arquivo contendo uma sequência de comandos em uma linguagem de programação especifica Esses comandosrespeitam regras de como serem escritos e quais são as palavras que podem

Leia mais

Lição 1 - Criação de campos calculados em consultas

Lição 1 - Criação de campos calculados em consultas 1 de 5 21-08-2011 22:15 Lição 1 - Criação de campos calculados em consultas Adição de Colunas com Valores Calculados: Vamos, inicialmente, relembrar, rapidamente alguns conceitos básicos sobre Consultas

Leia mais

Delphi 7 Aula 01 Área do Triângulo

Delphi 7 Aula 01 Área do Triângulo Delphi 7 Aula 01 Área do Triângulo Prof. Gilbert Azevedo da Silva I. Objetivos Conhecer o Ambiente Integrado de Desenvolvimento (IDE) do Delphi 7, Desenvolver a primeira aplicação no Delphi 7, Aprender

Leia mais

JAVA NETBEANS PGOO Prof. Daniela Pires Conteúdo

JAVA NETBEANS PGOO Prof. Daniela Pires Conteúdo Conteúdo Estruturas de repetição (loops, laços)... 2 WHILE (enquanto)... 2 DO... WHILE (faça... enquanto)... 2 FOR... 3 FOREACH... 4 EXERCICIO LOOP FOR... 4 Novo Projeto... 5 Controles SWING... 10 1 Estruturas

Leia mais

CONFIGURAÇÃO MINIMA EXIGIDA:

CONFIGURAÇÃO MINIMA EXIGIDA: Este tutorial parte do princípio que seu usuário já possua conhecimentos básicos sobre hardware, sistema operacional Windows XP ou superior, firewall, protocolo de rede TCP/IP e instalação de software.

Leia mais

JSP - ORIENTADO A OBJETOS

JSP - ORIENTADO A OBJETOS JSP Orientação a Objetos... 2 CLASSE:... 2 MÉTODOS:... 2 Método de Retorno... 2 Método de Execução... 2 Tipos de Dados... 3 Boolean... 3 Float... 3 Integer... 4 String... 4 Array... 4 Primeira:... 4 Segunda:...

Leia mais

Banco de Dados Microsoft Access: Criar tabelas. Vitor Valerio de Souza Campos

Banco de Dados Microsoft Access: Criar tabelas. Vitor Valerio de Souza Campos Banco de Dados Microsoft Access: Criar tabelas Vitor Valerio de Souza Campos Objetivos do curso 1. Criar uma tabela no modo de exibição Folha de Dados. 2. Definir tipos de dados para os campos na tabela.

Leia mais

Sistemas Operacionais

Sistemas Operacionais Sistemas Operacionais Aula 6 Estrutura de Sistemas Operacionais Prof.: Edilberto M. Silva http://www.edilms.eti.br Baseado no material disponibilizado por: SO - Prof. Edilberto Silva Prof. José Juan Espantoso

Leia mais

Gerenciamento de Arquivos e Pastas. Professor: Jeferson Machado Cordini jmcordini@hotmail.com

Gerenciamento de Arquivos e Pastas. Professor: Jeferson Machado Cordini jmcordini@hotmail.com Gerenciamento de Arquivos e Pastas Professor: Jeferson Machado Cordini jmcordini@hotmail.com Arquivo Todo e qualquer software ou informação gravada em nosso computador será guardada em uma unidade de disco,

Leia mais

Configurando o IIS no Server 2003

Configurando o IIS no Server 2003 2003 Ser ver Enterprise Objetivo Ao término, você será capaz de: 1. Instalar e configurar um site usando o IIS 6.0 Configurando o IIS no Server 2003 Instalando e configurando o IIS 6.0 O IIS 6 é o aplicativo

Leia mais

Apostilas OBJETIVA Escrevente Técnico Judiciário TJ Tribunal de Justiça do Estado de São Paulo - Concurso Público 2015. Caderno 1.

Apostilas OBJETIVA Escrevente Técnico Judiciário TJ Tribunal de Justiça do Estado de São Paulo - Concurso Público 2015. Caderno 1. Caderno 1 Índice MS-Windows 7: conceito de pastas, diretórios, arquivos e atalhos, área de trabalho, área de transferência, manipulação de arquivos e pastas, uso dos menus, programas e aplicativos, interação

Leia mais

Noções de. Microsoft SQL Server. Microsoft SQL Server

Noções de. Microsoft SQL Server. Microsoft SQL Server Noções de 1 Considerações Iniciais Basicamente existem dois tipos de usuários do SQL Server: Implementadores Administradores 2 1 Implementadores Utilizam o SQL Server para criar e alterar base de dados

Leia mais

Manual do Usuário Android Neocontrol

Manual do Usuário Android Neocontrol Manual do Usuário Android Neocontrol Sumário 1.Licença e Direitos Autorais...3 2.Sobre o produto...4 3. Instalando, Atualizando e executando o Android Neocontrol em seu aparelho...5 3.1. Instalando o aplicativo...5

Leia mais

Manual de Utilização

Manual de Utilização Manual de Utilização Versão 1.0 18/01/2013 Sempre consulte por atualizações deste manual em nossa página. O Cotação Web está em constante desenvolvimento, podendo ter novas funcionalidades adicionadas

Leia mais

Associação Educacional Dom Bosco Curso de Engenharia 1º ano

Associação Educacional Dom Bosco Curso de Engenharia 1º ano Formatação condicional utilizando o valor da célula O que é? Algumas vezes é preciso destacar os valores, ou seja, como colocar em vermelho ou entre parênteses, os negativos, e de outra cor os positivos,

Leia mais

Manual AGENDA DE BACKUP

Manual AGENDA DE BACKUP Gemelo Backup Online DESKTOP Manual AGENDA DE BACKUP Realiza seus backups de maneira automática. Você só programa os dias e horas em que serão efetuados. A única coisa que você deve fazer é manter seu

Leia mais

Guia de Início Rápido

Guia de Início Rápido Guia de Início Rápido O Microsoft Word 2013 parece diferente das versões anteriores, por isso criamos este guia para ajudar você a minimizar a curva de aprendizado. Barra de Ferramentas de Acesso Rápido

Leia mais

1) MANUAL DO INTEGRADOR Este documento, destinado aos instaladores do sistema, com informações de configuração.

1) MANUAL DO INTEGRADOR Este documento, destinado aos instaladores do sistema, com informações de configuração. O software de tarifação é uma solução destinada a rateio de custos de insumos em sistemas prediais, tais como shopping centers. O manual do sistema é dividido em dois volumes: 1) MANUAL DO INTEGRADOR Este

Leia mais

TUTORIAL: MANTENDO O BANCO DE DADOS DE SEU SITE DENTRO DO DOMÍNIO DA USP USANDO O SSH!

TUTORIAL: MANTENDO O BANCO DE DADOS DE SEU SITE DENTRO DO DOMÍNIO DA USP USANDO O SSH! UNIVERSIDADE DE SÃO PAULO (USP) ESCOLA DE ARTES, CIÊNCIAS E HUMANIDADES (EACH) TUTORIAL: MANTENDO O BANCO DE DADOS DE SEU SITE DENTRO DO DOMÍNIO DA USP USANDO O SSH! Autoria e revisão por: PET Sistemas

Leia mais

Informática Básica. Microsoft Word XP, 2003 e 2007

Informática Básica. Microsoft Word XP, 2003 e 2007 Informática Básica Microsoft Word XP, 2003 e 2007 Introdução O editor de textos Microsoft Word oferece um conjunto de recursos bastante completo, cobrindo todas as etapas de preparação, formatação e impressão

Leia mais

Banco de Dados Microsoft Access: Criar tabelas

Banco de Dados Microsoft Access: Criar tabelas Banco de Dados Microsoft Access: Criar s Vitor Valerio de Souza Campos Objetivos do curso 1. Criar uma no modo de exibição Folha de Dados. 2. Definir tipos de dados para os campos na. 3. Criar uma no modo

Leia mais