Tag Archives: .NET

.NET – Habilitando o OpenFileDialog no controle PropertyGrid

Poucou utilizado em sistemas tradicionais, infelizmente, o controle PropertyGrid disponibilizado a partir do .NET Framework 2.0 possui um forma prática de exibir características de um determinado objeto ou controle. Um tutorial bem completo deste pode ser visto aqui.

Tudo certo. Em um de seus usos, fiquei curioso em saber como alguns sistemas, inclusive o Visual Studio e outras IDEs Microsoft conseguir transformar algumas das caixas de valores do PropertyGrid campos OpenFileDialog, ou seja, quando este precisar conter o caminho de um arquivo, que aparecesse o pequeno botão a direta do campo para exibir tal funcionalidade.

Bom, a resposta é simples. A propriedade que irá expor o valor deve conter os seguintes atributos:

[EditorAttribute(typeof(System.Windows.Forms.Design.FileNameEditor),
typeof(System.Drawing.Design.UITypeEditor))]
public string CaminhoDoArquivo { get; set; }

A mágica é feita pelo atributo System.Windows.Forms.Design.FileNameEditor. O projeto precisa referenciar a bibliotecas System.Windows.Forms e System.Design para alcançar as classes mencionadas. A aparência fica dessa forma:

Também é possível adicionar a caixa de mapeamento de diretório, trocando o valor para System.Windows.Forms.Design.FolderNameEditor. O funcionamento do clique nos botões dispensa explicações, bem como a versão do código para VB.NET, certo?

Referências

http://stackoverflow.com/questions/170791/how-can-i-get-an-openfiledialog-in-a-custom-controls-property-grid

Bom proveito!

.NET : Obter o tamanho de um diretório com o .NET

Dica publicada pelo pessoal da BufaloInfo.

Não há ainda, nas classes do framework, um meio de obter o tamanho total de um diretório. Por isso o tamanho total de um diretório deve ser obtido pela soma do tamanho de seus arquivos e diretórios, da seguinte forma :

public static long Size(System.IO.DirectoryInfo dirInfo)
{
	long total = 0; 
 
	// Obtem o tamanho total dos arquivos no diretório
	foreach(System.IO.FileInfo file in dirInfo.GetFiles())
	total += file.Length; 
 
	// Obtem o tamanho total dos sub-diretórios da pasta
	foreach(System.IO.DirectoryInfo dir in dirInfo.GetDirectories())
	total += Size(dir); 
 
	return total;
}

É interessante observar que esta função é recursiva : Ao encontrar uma pasta a função chama a si mesma para poder calcular o tamanho da pasta e desta forma somar ao tamanho total.

No link abaixo há uma explicação mais detalha sobre Recursividade e os cuidados a considerar em seu uso:

http://pt.wikipedia.org/wiki/Recursividade

C# – Formatos Customizados para o DateTime

Este artigo é parte integrante do Curso Online de C#, disponibilizado neste link:

http://www.tomasvasquez.com.br/cursocsharp

O exemplos abaixo mostram as opções de formatação do tipo DateTime do C# utilizando o método String.Format. Estas opções também podem ser aplicadas através do método DateTime.ToString().

Formatos Customizados

São disponibilizados os seguintes formatos: y (ano), M (mês), d (dia), h (hora 12), H (hora 24), m (minuto), s (segundo), f (fração de segundo), F (fração de segundo com zeros omitidos), t (P.M ou A.M) e z (fuso horário).

O exemplos abaixo mostram o resultado de datas formatadas utilizando as opções acima:

// cria um objeto DateTime com o valor 2008-03-09 16:05:07.123
DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 123);
 
String.Format("{0:y yy yyy yyyy}", dt);  // "8 08 008 2008"   ano
String.Format("{0:M MM MMM MMMM}", dt);  // "3 03 Mar March"  mês
String.Format("{0:d dd ddd dddd}", dt);  // "9 09 Sun Sunday" dia
String.Format("{0:h hh H HH}",     dt);  // "4 04 16 16"      hora 12/24
String.Format("{0:m mm}",          dt);  // "5 05"            minuto
String.Format("{0:s ss}",          dt);  // "7 07"            segundo
String.Format("{0:f ff fff ffff}", dt);  // "1 12 123 1230"   fração de segundo
String.Format("{0:F FF FFF FFFF}", dt);  // "1 12 123 123"    com os zeros omitidos
String.Format("{0:t tt}",          dt);  // "P PM"            A.M. ou P.M.
String.Format("{0:z zz zzz}",      dt);  // "-6 -06 -06:00"   fuso horário

Também é possível utilizar os separadores de data (/) e hora (:) na string. O padrão sugerido é o inglês, mas estes serão substituídos para o caracterer específico da cultura/idioma configurado no sistema operacional em execução. Estes podem ser obtidos diretamente através das propriedades DateTimeForma­tInfo.DateSepa­rator e DateTimeForma­tInfo.TimeSepa­rator, sob o namespace System.Globalization.

Exemplos:

// separador de data na cultura alemã é o "."
// (ou seja, este será colocado no lugar no "/")
String.Format("{0:d/M/yyyy HH:mm:ss}", dt); // "9/3/2008 16:05:07" - Inglês (en-US)
String.Format("{0:d/M/yyyy HH:mm:ss}", dt); // "9.3.2008 16:05:07" - Alemão (de-DE)

Outros exemplos de formatos customizados:

// dia/mês sem e com zeros
String.Format("{0:d/M/yyyy}", dt);            // "9/3/2009"
String.Format("{0:dd/MM/yyyy}", dt);          // "09/03/2009"
 
// nomes de dia e mês
String.Format("{0:ddd, MMM d, yyyy}", dt);    // "Dom, Mar 9, 2009"
String.Format("{0:dddd, d de MMMM de yyyy}", dt);  // "Domingo, 9 de Março de 2009"
 
// ano com 2 e 4 dígitos
String.Format("{0:dd/MM/yy}", dt);            // "09/03/09"
String.Format("{0:dd/MM/yyyy}", dt);          // "09/03/2009"

Formatos Padrozinados para o DateTime

O DateTimeForma­tInfo define formatos padrão para cada região/país. Por exemplo , a propriedade ShortTimePattern representa uma string que contém o valor h:mm tt para a cultura en-US culture, enquanto para a cultura de-DE o valor é HH:mm.

A tabela abaixo demonstra o padrões definidos para o tipo DateTimeForma­tInfo e seus valores para a cultura en-US, que é a padrão do .NET Framework. A primeira coluna contém os “especificadores” para o método String.Format.

Especificado Propriededade do DateTimeFormatInfo Valor padrão (en-US)
t ShortTimePattern h:mm tt
d ShortDatePattern M/d/yyyy
T LongTimePattern h:mm:ss tt
D LongDatePattern dddd, MMMM dd, yyyy
f (combinação entre D e t) dddd, MMMM dd, yyyy h:mm tt
F FullDateTimePattern dddd, MMMM dd, yyyy h:mm:ss tt
g (combinação de d e t) M/d/yyyy h:mm tt
G (combinação de d e T) M/d/yyyy h:mm:ss tt
m, M MonthDayPattern MMMM dd
y, Y YearMonthPattern MMMM, yyyy
r, R RFC1123Pattern ddd, dd MMM yyyy HH':'mm':'ss 'GMT' (*)
s SortableDateTi­mePattern yyyy'-'MM'-'dd'T'HH':'mm':'ss (*)
u UniversalSorta­bleDateTimePat­tern yyyy'-'MM'-'dd HH':'mm':'ss'Z' (*)
(*) = independe da cultura

Os exemplos abaixo utilizam os especificadores padrão de formatação através do método String.Format e seus resultados, neste caso, para a cultura en-US. Lembrando que os mesmos especificadores podem ser utilizados com o método ToString().

String.Format("{0:t}", dt);  // "4:05 PM"                         ShortTime
String.Format("{0:d}", dt);  // "3/9/2008"                        ShortDate
String.Format("{0:T}", dt);  // "4:05:07 PM"                      LongTime
String.Format("{0:D}", dt);  // "Sunday, March 09, 2008"          LongDate
String.Format("{0:f}", dt);  // "Sunday, March 09, 2008 4:05 PM"  LongDate+ShortTime
String.Format("{0:F}", dt);  // "Sunday, March 09, 2008 4:05:07 PM" FullDateTime
String.Format("{0:g}", dt);  // "3/9/2008 4:05 PM"                ShortDate+ShortTime
String.Format("{0:G}", dt);  // "3/9/2008 4:05:07 PM"             ShortDate+LongTime
String.Format("{0:m}", dt);  // "March 09"                        MonthDay
String.Format("{0:y}", dt);  // "March, 2008"                     YearMonth
String.Format("{0:r}", dt);  // "Sun, 09 Mar 2008 16:05:07 GMT"   RFC1123
String.Format("{0:s}", dt);  // "2008-03-09T16:05:07"             SortableDateTime
String.Format("{0:u}", dt);  // "2008-03-09 16:05:07Z"            UniversalSortableDateTime

Efetuar os testes acima na cultura brasileira (pt-BR), o resultado será:

String.Format("{0:t}", dt);  // "16:05"					ShortTime
String.Format("{0:d}", dt);  // "9/3/2008"					ShortDate
String.Format("{0:T}", dt);  // "16:05:07"					LongTime
String.Format("{0:D}", dt);  // "domingo, 9 de março de 2008"		LongDate
String.Format("{0:f}", dt);  // "domingo, 9 de março de 2008 16:05"		LongDate+ShortTime
String.Format("{0:F}", dt);  // "domingo, 9 de março de 2008 16:05:07" 	FullDateTime
String.Format("{0:g}", dt);  // "9/3/2008 16:05"				ShortDate+ShortTime
String.Format("{0:G}", dt);  // "9/3/2008 16:05:07"				ShortDate+LongTime
String.Format("{0:m}", dt);  // "09 de março"				MonthDay
String.Format("{0:y}", dt);  // "março de 2008"				YearMonth
String.Format("{0:r}", dt);  // "Sun, 09 Mar 2008 16:05:07 GMT"		RFC1123
String.Format("{0:s}", dt);  // "2008-03-09T16:05:07"			SortableDateTime
String.Format("{0:u}", dt);  // "2008-03-09 16:05:07Z"			UniversalSortableDateTime

C# – static readonly vs. const

C#
O pessoal do grupo em que participo colocou essa pergunta e achei bacana comentar aqui.

Qual a diferença entre utilizar static readonly ou const ? Tem algum
que é mais performatico?

const é avaliado em tempo de compilação, enquanto static readonly em tempo de execução. Isso permite que no static readonly você inicialize uma classe ou struct, enquanto no const você só pode usar tipos primários (porque são compilados).

O readonly pode ser inicializado dentro do construtor. Ou seja, dependendo do construtor que você usar, o readonly pode ter valores diferentes. Já o const não. Mas isso só vale pra readonly non-static, pq só existe um construtor static pra classe.

Tem mais um fator, muito importante aliás, principalmente na utilização de componentes.

Em quase todas as linguagens, const é apenas um facilitador para substituição de valores. Quando você declara um const e atribui um valor a ele, por exemplo, um inteiro de valor 5, ao compilar, todos os lugares que referenciam sua const vão ter o valor substituído pelo inteiro 5. Por isso a performance.

No caso do static reanonly, isso não acontece pois, apesar da variável ser somente leitura, ela ainda é uma “variável” e sempre será referenciada.

Um caso típico de onde não se deve usar const é em bibliotecas. Por exemplo, você criar uma lib que vai conter a string de conexão. Você a coloca em uma const. Na compilação, todos os valores que refenciam a
string de conexão terão seus valores substituídos pelo valor da const. Ok, era o que você queria. Mas, caso você preciso alterar a string de conexão, você obviamente vai recompilar e publicar somente a lib com a
informação. O fato é, ao fazê-lo, todo o resto do código só conhece o valor anterior da const.

Para ver um exemplo bem simples, crie o seguinte programa no notepad mesmo:

1
2
3
4
5
6
7
8
9
10
11
using System;
 
public class TestConst
{
        public static void Main(string[] args)
        {
                const string MinhaString = "bla";
                Console.WriteLine(MinhaString);
        }
 
}

Compile com o csc.exe. Em seguida, abra o assembly com o ILDASM ou mesmo o Reflector. Veja o resultado.