dez 13

Este erro, ao contrário do que os outros pensam, não é do Chrome ou do Safari e sim do próprio ASP.NET.

Para gerar o código JavaScript do menu, o ASP.NET verifica qual é o browser do cliente, e se ele suporta ou não JavaScript. Acontece que esta verificação falha em alguns browsers como o Sarafi e consequentemente o Chrome (pois o Chrome foi baseado no Safari), e o  ASP.NET então devolve um código que não funciona. Para corrigir isto devemos “forçar” o ASP.NET a executar o JavaScript, para isto setamos a propriedade Page.ClientTarget com o valor “uplevel”. Assim informamos que o cliente possui um moderno “uplevel” browser.

Devemos fazer isto para todas as páginas que utilizarão o menu. O código deverá estar dentro do evento Page_Init da página. Ex:

     protected void Page_PreInit(object sender, EventArgs e)
    {
        if (Page.Request.ServerVariables["http_user_agent"].ToLower().Contains("safari"))
        {
            Page.ClientTarget = "uplevel";
        }
    }

Neste código, fazemos uma verificação se o user_agent possui a palavra safari, que servirá também pro chrome  e, se sim, forçamos o uplevel.

Para evitar de “copiar” e “colar” o mesmo código em todas as páginas, você poderá aproveitar o que há de melhor da programação orienteda a objetos, a herânça. Para isto crie uma classe herdando de System.Web.UI.Page e coloque este código nela. Para todas as suas páginas, ao invés de herdar diretamente de System.Web.UI.Page, você herda da classe que acabou de criar.


View this Post in: English French Italian Spanish

out 19

Já mostrei aqui como obter o dia da semana por extenso no charp. Para poder escrever a data completa no formato “[dia da semana], [dia] de [mês] de [ano]” basta obter separadamente cada uma das partes como no exemplo a seguir.

        CultureInfo culture = new CultureInfo("pt-BR");
        DateTimeFormatInfo dtfi = culture.DateTimeFormat;

        int dia = DateTime.Now.Day;
        int ano = DateTime.Now.Year;
        string mes = culture.TextInfo.ToTitleCase(dtfi.GetMonthName(DateTime.Now.Month));
        string diasemana = culture.TextInfo.ToTitleCase(dtfi.GetDayName(DateTime.Now.DayOfWeek));
        string data = diasemana + ", " + dia + " de " + mes + " de " + ano;

        Response.Write(data);

O método ToTitleCase da classe TextInfo serve para converter a primeira letra da palavra para maiúsculo e os métodos GetMonthName e GetDayName da classe DateTimeFormatInfo servem para pegar o nome do mês e do dia da semana respectivamente.

No final a variável data conterá o dia por extenso. Por exemplo:

Domingo, 19 de Outubro de 2008

Para os dias menores que 10, se você preferir escreve-los com o zero antes basta aplicar o método ToString a variável dia.

string data = diasemana + ", " + dia.ToString("00") + " de " + mes + " de " + ano;

View this Post in: English French Italian Spanish

out 15

Depois de alguns dias pesquisando, encontrei algumas soluções viáveis para enviar um arquivo diretamente para a impressora (sem abrir janelas de diálogo), cada uma com suas limitações.


Solução 1: Fazer uma cópia do arquivo para o local da impressora

 

No prompt do DOS basta utilizar o comando:

copy nome_arquivo nome_impressora

O equivalente em C# é:

System.IO.File.Copy(nome_arquivo , nome_impressora);

Onde nome_arquivo é o nome físico completo do arquivo e nome_impressora é o nome do compartilhamento da impressora composto pelo IP ou nome da máquina mais o nome do compartilhamento.

Limitação: Imprime somente arquivos texto e a impressora deverá estar compartilhada.


Solução 2: Utilizar o comando print do windows.

Esta foi a melhor solução que encontrei. A idéia é utilizar o comando “print” do shell do Windows. Ao executar o comando, o Windows irá abrir o programa padrão estabelecido pelo tipo do arquivo e imprimir automaticamente, fechando o programa após a impressão.

Em Delphi utiliza-se o comando ShellExecute para executar um comando shell.

ShellExecute(Handle, 'print',PChar('arquivo'), nil,nil,SW_SHOW);

No Framework .Net não existe esta função, no entanto ela está implementada na dll shell32.dll do Windows. Para utiliza-la em C#, VB6 ou VB .Net devemos criar uma referência para a mesma.

[DllImport("shell32.dll", EntryPoint = "ShellExecute")]
public static extern int ShellExecuteA(int hwnd, string lpOperation,
     string lpFile, string lpParameters, string lpDirectory, int nShowCmd);

Para utilizar a directiva DllImport é preciso referênciar o namespace System.Runtime.InteropServices.
Veja o exemplo a seguir utilizado em um projeto do tipo Windows Application.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace ImprimeArquivo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                Form1.ShellExecuteA(this.Handle.ToInt32(), "print", ofd.FileName, null, null, 0);
            }
        }

        [DllImport("shell32.dll", EntryPoint = "ShellExecute")]
        public static extern int ShellExecuteA(int hwnd, string lpOperation,
              string lpFile, string lpParameters, string lpDirectory, int nShowCmd);
    }
}

Solução 3: http://support.microsoft.com/kb/322091/pt-br


View this Post in: English French Italian Spanish

out 06

Para saber a versão de uma dll criada a partir de um projeto do tipo Class Library basta utilizar o código:

typeof(NomedaSuaClasse).Assembly.GetName().Version;

Ou, se você chamar a instrução de dentro da classe, poderá fazer:

this.GetType().Assembly.GetName().Version;

Esses métodos retornam um objeto do tipo Version, que pode ser utilizado para pegar separadamente cada tipo de versão. Por exemplo, a versão de compilação, a maior verão, a menor versão, etc…

O código abaixo exemplifica o uso destes métodos em uma classe que pode ser chamada por exemplo em uma aplicação Web ou WinForm.

public class Info
{
    public static Version GetVersion()
    {
        return typeof(Info).Assembly.GetName().Version;
    }

    public static string GetVersionString()
    {
        Version version = Info.GetVersion();
        string versionstring = version.Major + "." + version.Minor +
            "." + version.Build + "." + version.Revision;
        return versionstring;
    }
}

Para chamar este método em sua aplicação faça por exemplo:

label.Text = "Versão:" + Info.GetVersionString();

Se estiver trabalhando com WinForms, você poderá usar o código abaixo para saber a versão do exe de sua aplicação:

Assembly.GetEntryAssembly().GetName().Version

Da mesma maneira que no exemplo anterior com a dll, poderá ser criado uma classe somente para retornar esta informação.

Obs.: Para alterar a versão da dll basta ir nas propriedades do projeto e na guia Application clique no botão “Assembly Information” como na figura abaixo.


View this Post in: English French Italian Spanish

out 05

Para pegar o valor de uma string de conexão do Web.Config basta utilizar a classe ConfigurationManager. Veja um exemplo:

string cs = ConfigurationManager.ConnectionStrings["strConn"].ConnectionString;

Onde strConn é o nome dado a sua string de conexão no Web.Config. Veja um exemplo do Web.Config:

<?xml version="1.0"?>
<configuration>
    <connectionStrings>
       <add name="strConn"
	connectionString="Data Source=192.168.0.1;Initial Catalog=Banco;
User ID=Usuario;Password=Senha;"
	providerName="System.Data.SqlClient"/>
    </connectionStrings>   
</configuration>

Se você se deparar com o erro “The name ‘ConfigurationManager’ does not exist in the current context” é porque provavelmente você está tentando pegar o valor desta string em um projeto do tipo Class Library. Para solucionar este problema basta referenciar no seu projeto a dll System.configuration.


View this Post in: English French Italian Spanish

set 15

Para limpar todos os componentes da página basta buscar por cada tipo individualmente utilizando o método Controls(). O método Controls() está presente em todas as classes que herdam de Control.

O código abaixo percorre todos os componentes do formulário da página verificando os que são TextBox. Em seguida é dado um cast no objeto para poder utilizar sua propriedade Text e assim limpar seu conteúdo.

foreach (Control componente in Page.Form.Controls)
{
    //Verificando se é um text box e limpando quando for
    if (componente.GetType() == typeof(TextBox))
        ((TextBox)componente).Text = "";
}

O mesmo pode ser feito quanto aos Dropdown List, Radios, etc…

É preciso lembrar que se um determinado componente está dentro de um container, deverá ser feito o loop dos Controls deste container. Por exemplo, se sua página está dentro de um MasterPage você deverá fazer.

foreach (Control componente in Page.Master.FindControl("ContentPlaceHolder1").Controls)
{
    //Verificando se é um text box e limpando quando for
    if (componente.GetType() == typeof(TextBox))
        ((TextBox)componente).Text = "";
}

Substitua ContentPlaceHolder1 pelo nome de seu ContentPlaceHolder


View this Post in: English French Italian Spanish

ago 27

Se você já utilizou os componentes AJAX da Microsoft, já deve ter tido esse mesmo problema. Quando você utiliza o UpdatePanel por exemplo, como tudo na página é atualizado de forma dinâmica (sem refresh), o ClientScript perde a sua funcionalidade pois depende de um PostBack inteiro da página para que assim execute os scripts. Pesquisando um pouco, encontrei a solução: a classe ScriptManager. A forma de utilização da classe é praticamente a mesma no ClientScript, veja:

Registrando um script sem o AJAX com o ClientScript.

ClientScript.RegisterClientScriptBlock(
   type, key, script, addScriptTags);

Ex.:

Page.ClientScript.RegisterStartupScript(
   Page.GetType(), "Alert", "alert('Olá Mundo')", true);

Registrando o script com AJAX com o ScriptManager

ScriptManager.RegisterStartupScript(
   control, type, key, script, addScriptTags);

Ex.:

ScriptManager.RegisterStartupScript(
   Page, Page.GetType(), "Alert", "alert('Olá Mundo')", true);

A classe ScriptManager está no namespace System.Web.UI, mas é preciso acrescentar  uma referência à dll System.Web.Extensions.dll


View this Post in: English French Italian Spanish

jul 04

Segue abaixo um exemplo de como, em tempo de execução, adicionar uma folha de estilo (css) a uma página aspx

C#

//Capturando o “Header” da pagina
HtmlHead header = (HtmlHead)Page.Header;
//Setendo o CSS Link
HtmlLink link = new HtmlLink();
link.Attributes.Add("href", Page.ResolveClientUrl("~/estilo.css"));
link.Attributes.Add("type", "text/css");
link.Attributes.Add("rel", "stylesheet");
//Adicionando CSS Link no Hearder da página
header.Controls.Add(link);

View this Post in: English French Italian Spanish

mar 16

Para manipular os dados de um GridView, podemos utilizar os eventos RowCreated ou RowDataBound.

Ao dar um duplo clique sobre um dos eventos citados, o Visual Studio criará um método com dois parâmetros: “sender” do tipo object e “e” do tipo GridViewRowEventArgs

Este método é chamados para cada linha do grid, inclusive o cabeçalho, rodapé e paginamento.

O parâmetro “e” contém informações sobre a linha atual do GridView. Usando a propriedade Rows.Cells deste objeto podemos obter os dados diretamente no grid.

e.Row.Cells[indice]

onde indice é o índice dos seus dados conforme foi criado com a opção Edit Coluns do GridView Tasks. Lembrando que o índice começa com zero.

Esta opção é meio fraquinha pois as colunas com a opção visibe setada como false não retornam os dados, e os campos null são retornados como caracteres de espaço em html.

A melhor forma é pegar os dados pela propriedade DataItem. Como esta propriedade retorna um objeto do tipo object, é preciso dar um cast para converter para o tipo apropriado. No caso de se utilizar o GridView ligado a um DataSource para mostrar os dados de um Database diretamente, o cast deverá ser feito da seguinte forma.

System.Data.DataRowView vRow = (System.Data.DataRowView)e.Row.DataItem;

Para manipular os dados é só utilizar o objeto vRow:

vRow["SeuCampo"]

Caso o DataSource esteja sendo utilizado para mostrar dados vindo de um Object, o cast deverá ser feito utilizando a classe do objeto em questão. Ex.:

MinhaClasse meuobjeto  = (MinhaClasse)e.Row.DataItem;

Daí é só utilizar as propriedades e métodos da sua classe.


View this Post in: English French Italian Spanish

mar 03

// using System.Globalization
CultureInfo culture = new CultureInfo("pt-BR");
DateTimeFormatInfo dtfi = culture.DateTimeFormat;
string data = dtfi.GetDayName(DateTime.Now.DayOfWeek);

View this Post in: English French Italian Spanish