Tag Archives: C#

Microsoft libera versão final do Service Pack 1 das ferramentas .Net Framework 3.5 e Visual Studio 2008

A Microsoft liberou a versão final do Service Pack 1 das ferramentas .Net Framework 3.5 e Visual Studio 2008.

Esses primeiros pacotes de atualizações são lançados agora, nove meses após a chegada dos dois produtos ao mercado. Segundo a Microsoft, os pacotes incluem não apenas correções, mas também alterações que atendem a sugestões feitas por usuários.

O SP1 do Visual Studio 2008, por exemplo, traz como novidade o suporte ao SQL Server 2008 – que está sendo lançado agora – e novos componentes, como o Ribbon, para incluir nos aplicativos faixas de opções no estilo das usadas no Office 2007. Esse último recurso está disponível para as linguagens Visual Basic e Visual C++.

Ainda segundo a empresa, o SP1 do .Net Framework 3.5 oferece melhorias de desempenho de 20% a 45% para aplicações baseadas em WPF (Windows Presentation Foundation). Esse ganho, sustenta a Microsoft, é obtido sem nenhuma alteração no código existente. Os dois pacotes SP1 também incorporam mudanças que têm o objetivo de facilitar o desenvolvimento das aplicações Windows que utilizam ASP.Net.

Os dois pacotes podem ser baixados nos seguintes endereços:

Visual Studio Service Pack 1

.Net Framework Service Pack 1

Fonte: INFO

C# – Trocando a navegação dos controles Windows do TAB para o ENTER

Essa é um pouco velha, mas tão eminente quanto a necessidade de migração de sistemas legados.

Poderia citar inúmeros motivos que levam a essa “cultura” de utilização de sistemas comerciais, mas vou enfatizar alguns:

  • Legado de sistemas orientados a caracter, geralmente feitos em CLIPPER
  • Legado de linguagens de quarta-geração, ou pelo daqueles aplicativos que o tentam ser, como Access e FoxPro
  • Facilidade na utlização do teclado numérico, já que nele além das teclas númericas há também o ENTER facilitando o acesso

O fato é que, é quase certo que os usuários do sistema antigo solicitarão que a navegação entre campos seja trocada do tradicional TAB pelo ENTER.

Para fazer isso em C# (e qualquer outra linguagem .NET, guardadas as devidas conversões), primeiramente é preciso habilitar a propriedade KeyPreview do Formulário principal para que o controle esteja habilitado a interceptar as teclas digitadas.

Depois, para trocar a navegação, bastaria interceptar o evento KeyDown e fazer o tratamento. Mas para fazer um tratamento mais completo, vamos inteceptar o KeyDown para suprimir o ENTER e o KeyUp para trocar a tecla enviada. O código abaixo faz isso:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/// inibe a ação do Enter para evitar o comportamento de
/// Accept em alguns casos
private void _ctrl_KeyDown(object sender, KeyEventArgs e)
{
	if (e.KeyCode == Keys.Enter)
		e.SuppressKeyPress = true;
}
/// adiciona a tratativa à tecla Enter e envia o TAB para
/// promover a navegação
private void _ctrl_KeyUp(object sender, KeyEventArgs e)
{
	if (e.KeyCode == Keys.Enter)
	{
		// SendKeys.Send("{TAB}");
		_ctrl.FindForm().SelectNextControl(_ctrl, true, true, true, false);
	}
}

Percebam que no KeyUp há uma parte do código comentada (SendKeys.Send(“{TAB}”);) que faria com que a tecla TAB fosse acionada no lugar do ENTER, porém, é mais elegante usar o método SelectNextControl do objeto Form, que faz a ação sem a necessidade de simular um comportamento, o que em alguns casos pode causar um comportamento não desejado.

Isso resolve o problema. Para tentar ajudar um pouco mais, disponilizo abaixo um método mais completo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/// <summary>
/// Adiciona o comportamento de navegação através da tecla Enter,
/// da mesma forma como o TAB
/// </summary>
/// <param name="_ctrl">O controle pai que contém os controles em que
/// serão adicionados os eventos</param>
public static void TrocaTABporEnter(Control _ctrl)
{
	if (_ctrl.HasChildren)
	{
		foreach (Control _child in _ctrl.Controls)
		{
			if (_ctrl.HasChildren)
				TrocaTABporEnter(_child);
		}
	}
	else
	{
		///Não funciona para Numeric Up Down
		if (_ctrl is TextBox ||
		_ctrl is MaskedTextBox ||
		_ctrl is ListBox ||
		_ctrl is CheckBox ||
		_ctrl is TabPage ||
		_ctrl is DateTimePicker ||
		_ctrl is ComboBox)
		{
			/// inibe a ação do Enter para evitar o comportamento de
			/// Accept em alguns casos
			_ctrl.KeyDown += delegate(object sender, KeyEventArgs e)
			{
				if (e.KeyCode == Keys.Enter)
					e.SuppressKeyPress = true;
			};
			/// adiciona a tratativa à tecla Enter e envia o TAB para
			/// promover a navegação
			_ctrl.KeyUp += delegate(object sender, KeyEventArgs e)
			{
				if (e.KeyCode == Keys.Enter)
				{
					// SendKeys.Send("{TAB}");
					_ctrl.FindForm().SelectNextControl(_ctrl, true, true, true, false);
				}
			};
		}
	}
}

Este método pode ser chamado em qualquer momento do seu código e faz com que todos os controles filhos do controle passado por parâmetro adiquiram o comportamento, sem a necessidade de mapear o evento para todos os controles.

Como comentado, o código não funciona com alguns controles, em particular o NumericUpDown. Para que isso seja possível, é preciso sobrescrever alguns métodos da classe, mas isso já outra história.

Abraços

Tomás Vásquez
www.tomasvasquez.com.br

.NET – Treinando LINQ no LINQPad

Que o LINQ é uma das grandes novidades da nova versão do .NET Framework não há a menor dúvida.

Não minha intenção falar sobre ele aqui. Para saber mais sobre o recurso, colocarei no fim deste post alguns links para artigos relacionados. Quem sabe até escreve a respeito em outro post, mas não vou entrar em detalhes.

O grande problema, ou pelo menos o que pude perceber, é que não é tão fácil treinar LINQ como se treina SQL. No caso deste último, geralmente os bancos de dados oferecem um interface para disparar tais comandos e até mesmo montá-los de forma visual, obtendo os resultados automaticamente na tela. No caso do LINQ, seria necessário ficar montando entidades ou classes que representassem as tabelas do banco, para aí sim começar a fazer seus testes.

Mas para variar, sempre dá para contar com os colegas que constroem ferramentas bacanas que facilitam tanto o processo de produção como o de aprendizagem. Neste caso, o camara Joseph Albahari publicou um pequeno aplicativo que permite criar consultas no padrão LINQ sobre bancos de dados, assim como é feito no editor de cosultas do SQL Management Studio ou Query Analyzer.

O visual da ferramenta pode ser conferido abaixo:

LINQPad
LINQPad - Clique na Imagem para ampliar

Ao adicionar uma conexão, ele mapeia todos as tabelas do banco e produz virtualmente as entidades que se referem a cada uma das tabelas, permitindo disparar o código LINQ que faz a consulta, da mesma forma que se faria no Visual Studio, porém com resultado imediato.

A LINQPad é simples e não precisa de instalação. Basta fazer o download do arquivo e sair trabalhando.

<< Download do LINQPad >>

Site do autor: http://www.linqpad.net/

Abraços

Tomás Vásquez
www.tomasvasquez.com.br

C# – Usando o InputBox no C#

Desenvolvedores que vieram no Visual Basic e migram para qualquer que seja a linguagem, normalmente sentem falta de algumas funções “tradicionais”. Isso se resolve algumas formas, e no caso dos desenvolvedores C#, o caminho mais curto seria adicionar uma referência a dll Microsoft.VisualBasic, fazendo com que todas as funções legadas da linguagem tornem disponíveis.

Mas depender de uma linguagem antiga às vezes dá um mal estar, além do fato de, sabendo de todo o poder que a nova linguagem dispõe, pra usar as funções antigas?

Pois bem, para uma necessidade extremamente simples em um dos sistemas que estive construindo, precisei coletar um dado de forma tão simples que não fazia sentido algum criar um form para isso. Nisso, antes de sair fazendo alguma coisa, decidi dar uma pesquisada na net para ver se alguém já tinha aprontado alguma coisa nesse sentido, e realmente encontrei. O código abaixo é um form que possuir as mesmas características do InputBox:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
 
namespace System
{
	/// <summary>
	/// Summary description for InputBox.
	///
	public class InputBoxDialog : System.Windows.Forms.Form
	{
 
		#region Windows Contols and Constructor
 
		private System.Windows.Forms.Label lblPrompt;
		private System.Windows.Forms.Button btnOK;
		private System.Windows.Forms.TextBox txtInput;
		/// <summary>
		/// Required designer variable.
		///
		private System.ComponentModel.Container components = null;
 
		public InputBoxDialog()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
 
			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}
 
		#endregion
 
		#region Dispose
 
		/// <summary>
		/// Clean up any resources being used.
		///
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose(disposing);
		}
 
		#endregion
 
		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		///
		private void InitializeComponent()
		{
			this.lblPrompt = new System.Windows.Forms.Label();
			this.txtInput = new System.Windows.Forms.TextBox();
			this.btnOK = new System.Windows.Forms.Button();
			this.btnCancel = new System.Windows.Forms.Button();
			this.SuspendLayout();
			//
			// lblPrompt
			//
			this.lblPrompt.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
			| System.Windows.Forms.AnchorStyles.Left)
			| System.Windows.Forms.AnchorStyles.Right)));
			this.lblPrompt.BackColor = System.Drawing.SystemColors.Control;
			this.lblPrompt.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.lblPrompt.Location = new System.Drawing.Point(12, 9);
			this.lblPrompt.Name = "lblPrompt";
			this.lblPrompt.Size = new System.Drawing.Size(302, 82);
			this.lblPrompt.TabIndex = 3;
			//
			// txtInput
			//
			this.txtInput.Location = new System.Drawing.Point(8, 100);
			this.txtInput.Name = "txtInput";
			this.txtInput.Size = new System.Drawing.Size(379, 20);
			this.txtInput.TabIndex = 0;
			//
			// btnOK
			//
			this.btnOK.Location = new System.Drawing.Point(320, 10);
			this.btnOK.Name = "btnOK";
			this.btnOK.Size = new System.Drawing.Size(75, 25);
			this.btnOK.TabIndex = 4;
			this.btnOK.Text = "&OK";
			this.btnOK.UseVisualStyleBackColor = true;
			this.btnOK.Click += new System.EventHandler(this.BtnOKClick);
			//
			// btnCancel
			//
			this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
			this.btnCancel.Location = new System.Drawing.Point(320, 41);
			this.btnCancel.Name = "btnCancel";
			this.btnCancel.Size = new System.Drawing.Size(75, 25);
			this.btnCancel.TabIndex = 5;
			this.btnCancel.Text = "&Cancel";
			this.btnCancel.UseVisualStyleBackColor = true;
			this.btnCancel.Click += new System.EventHandler(this.BtnCancelClick);
			//
			// InputBoxDialog
			//
			this.AcceptButton = this.btnOK;
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.BackColor = System.Drawing.SystemColors.Control;
			this.CancelButton = this.btnCancel;
			this.ClientSize = new System.Drawing.Size(398, 128);
			this.Controls.Add(this.btnCancel);
			this.Controls.Add(this.btnOK);
			this.Controls.Add(this.txtInput);
			this.Controls.Add(this.lblPrompt);
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
			this.MaximizeBox = false;
			this.MinimizeBox = false;
			this.Name = "InputBoxDialog";
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
			this.Text = "InputBox";
			this.Load += new System.EventHandler(this.InputBox_Load);
			this.ResumeLayout(false);
			this.PerformLayout();
		}
		private System.Windows.Forms.Button btnCancel;
		#endregion
 
		#region Private Variables
		string formCaption = string.Empty;
		string formPrompt = string.Empty;
		string inputResponse = string.Empty;
		string defaultValue = string.Empty;
		#endregion
 
		#region Public Properties
		public string FormCaption
		{
			get { return formCaption; }
			set { formCaption = value; }
		} // property FormCaption
		public string FormPrompt
		{
			get { return formPrompt; }
			set { formPrompt = value; }
		} // property FormPrompt
		public string InputResponse
		{
			get { return inputResponse; }
			set { inputResponse = value; }
		} // property InputResponse
		public string DefaultValue
		{
			get { return defaultValue; }
			set { defaultValue = value; }
		} // property DefaultValue
 
		#endregion
 
		#region Form and Control Events
		private void InputBox_Load(object sender, System.EventArgs e)
		{
			this.txtInput.Text = defaultValue;
			this.lblPrompt.Text = formPrompt;
			this.Text = formCaption;
			this.txtInput.SelectionStart = 0;
			this.txtInput.SelectionLength = this.txtInput.Text.Length;
			this.txtInput.Focus();
		}
		#endregion
 
		void BtnOKClick(object sender, EventArgs e)
		{
			InputResponse = this.txtInput.Text;
			this.Close();
		}
 
		void BtnCancelClick(object sender, EventArgs e)
		{
			this.Close();
		}
	}
}

Abaixo segue a função estática que permite a chamada da mesma forma que se fazia no VB:

1
2
3
4
5
6
7
8
9
10
11
public static string InputBox(string prompt,string title, string defaultValue)
{
	InputBoxDialog ib = new InputBoxDialog();
	ib.FormPrompt = prompt;
	ib.FormCaption = title;
	ib.DefaultValue = defaultValue;
	ib.ShowDialog();
	string s = ib.InputResponse;
	ib.Close();
	return s;
}

Além de resolver o problema, deu também aquele saudosismo. Bom, mesmo assim vou continuar no C#.

Referência: http://csharp.wikia.com/

Abraços

Tomás Vásquez
www.tomasvasquez.com.br