sexta-feira, 31 de agosto de 2018
Como criar um relatório CrystalReport sem banco de dados
A um tempo tive problemas com as conexões do crystal report. Quando passava a aplicação para outros computadores tinha que trocar também a conexão, porem muitas vezes esquecia de fazer esse processo e ficava horas e horas para descobrir onde estava o problema. Por isso optei por usar os crystal report sem conexão directa a base de dados.
O que vamos ver é pequeno exemplo de como criar um relatório de Lista de Países com o Crystal Reports a partir de uma lista de objectos sem ter uma banco de dados.
Passo 1
Certifique-se de ter Crystal Report para o Visual Studio instalado.Passo 2
Cria um novo projecto WinForm. Neste exemplo criei um projecto com nome TesteCrystalSemDB. A seguir, cria uma classe País como o seguinte:public class Pais
{
public Pais(int codigo,string nome)
{
this.Codigo = codigo;
this.NomePais = nome;
}
public int Codigo { get; set; }
public string NomePais { get; set; }
}
Passo 3
Adicione um novo formulário com o nome FormPaises, e adicione o seguinte método:
private List<Pais> GetListaPaises()
{
List<Pais> Paises = new List<Pais>
{
new Pais(1, "Angola"),
new Pais(2, "Brasil"),
new Pais(3, "Portugal"),
new Pais(6, "Moçambique"),
new Pais(7, "Cabo-Verde"),
new Pais(8, "Namibia")
};
return Paises;
}
Passo 4
Adicione um DataSet. Nomeia-o por DataSet1 como na figura abaixo:Dentro da DataSet adicione uma DataTable com o nome de Pais, e cria as colunas com os mesmos nome dos atributos da classe Pais. ( Esse é o maior segredo ;). Confirma na figura acima.
Passo 5
Adicione ao projecto um Crystal Report e nomeio-o por ReportPaises2, clique em Add.
Aparecerá uma caixa como a que se segui, as opeções criar um nome documento de crystal report, escolha a segunda, Relatório em Branco e clica OK.
Passo 6
Restamos definir a fonte de dados ou DataSet no nosso Crystal Report. Para isso, vai em Fiel Explorer dê um clique direito na Database Fiel para selecionar o opção Database Expert conforme a figura abaixo mostra:

No assistente, expande Dados de Projecto > Conjuntos de Dados ADO.NET > TesteCrystalSemDB.DataSet1e seleccione a DataTable Pais.
Passo 7
Volte para o formulário FormPaises, vai à ToolBox, escolha o CrystalReportViewer, coloque-o ao formulário e nomeia-o por crystalReportViewer1.
Selecione este novo componente e (1) no seu canto superior direito dê um clique para ver a lista de propriedades, (2) clique em "Escolher um Crystal Report, (3) Selecione o relatorio que criamos "ReportPaises2", (4) clique em OK.
private void FormPaises_Load(object sender, EventArgs e)
{
Reports.ReportPaises2 cr = new Reports.ReportPaises2();
crystalReportViewer1.ReportSource = cr;
cr.SetDataSource(GetListaPaises());
}
Pronto, o relatório está feito, basta pressionar F5 para testar.
Bonus
A propriedade SetDataSource do CrystalReport pode receber qualquer colecção de dados. Por isso aproveita essa propriedade colocar a tua fonte da dados. Como eu disse no inicio deste post, não acho viável os dados serem dependentes da conexão do Crystal Report.sexta-feira, 27 de julho de 2018
Como definir a resolução do monitor com o C#
Tive dificuldade em definir uma resolução de tela dinâmica quando estava fazendo um aplicativo. Eu presumo que a maioria de nós tenha acontecido conosco ou tenha enfrentado esses tempos em algum lugar ao longo de nosso ciclo de vida de engenharia. Porque, como todos sabemos, a resolução da tela do usuário pode não ser a mesma da tela do ambiente de desenvolvimento.Neste post vou entregar o que eu encontrei como uma solução para o desafio discutido.
Então vamos ver:
- Como obter a resolução do monitor do usuário.
- Como alterar a resolução do monitor do usuário para produto compatível
- Como proteger a resolução do monitor do usuário.
Como obter a resolução do monitor do usuário
O acesso à tela do usuário está sendo facilitado pela classe Screen, que é fornecida junto com a estrutura .NET. E pode acessar a resolução da tela do usuário atual por meio de uma propriedade Screen.PrimaryScreen que é estática disponível na classe Screen:
public static Screen PrimaryScreen {get;}
A propriedade acima mencionada é somente leitura e retorna um tipo Screen. E a lógica abaixo mostra como usar o tipo Screen para acessar a resolução da tela do usuário:
Screen screen = Screen.PrimaryScreen;
int S_width=screen.Bounds.Width;
int S_height=screen.Bounds.Height;
Como alterar a resolução do monitor do usuário para produto compatível
Antes de seguir em direção ao nosso próximo objetivo, deixe-me falar sobre a parte não gerenciada dessa implementação. Ao contrário das linguagens tradicionais, a estrutura .NET mantém uma etapa distinta enquanto aproveita o código gerenciado e não gerenciado. Pessoalmente, quando escrevi este artigo, nunca encontrei nenhum código gerenciado que faça esse tratamento de resolução. E isso é o que me fez pensar em explorar algumas APIs do Win32.
Como o escopo deste artigo está limitado ao código gerenciado, não discutirei nada sobre código não gerenciado. Mas, apesar disso, podemos usar o atributo DllImport para ler a definição de código não gerenciado em seu ambiente gerenciado. Neste caso, estaremos usando a API User32.dll, que facilita a resolução dinâmica e possui duas funções relacionadas à alteração da resolução da tela.
- EnumDisplaySettings
- ChangeDisplaySettings
class User32
{
[DllImport("user32.dll")]
public static extern int EnumDisplaySettings (string deviceName, int modeNum, ref DEVMODE devMode );
[DllImport("user32.dll")]
public static extern int ChangeDisplaySettings(
ref DEVMODE devMode, int flags);
public const int ENUM_CURRENT_SETTINGS = -1;
public const int CDS_UPDATEREGISTRY = 0x01;
public const int CDS_TEST = 0x02;
public const int DISP_CHANGE_SUCCESSFUL = 0;
public const int DISP_CHANGE_RESTART = 1;
public const int DISP_CHANGE_FAILED = -1;
}
Como sabemos, o [DllImport("user32.dll")] é um trabalho explícito antes de injetar uma implementação não gerenciada em nosso ambiente gerenciado.
public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);
DEVMODE é uma estrutura explicada na documentação da plataforma, bem como incluída no Visual Studio .NET. A estrutura é definida em C#, por isso não se preocupar!
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
...
}
Você pode dar uma olhada no código-fonte clicando aqui e aplicar essa lógica a qualquer evento desejado.
Esteja ciente de que, os tipos têm o tamanho certo e que as seqüências de comprimento fixo são apropriadamente definida. Neste caso, WORD mapeia para short, DWORD para int e short permanece como short.
DEVMODE dm = new DEVMODE();
dm.dmDeviceName = new String(new char[32]);
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf (dm);
if (0 !=User32.EnumDisplaySettings(null,User32.ENUM_CURRENT_SETTINGS,ref dm))
{
Neste ponto, a estrutura DEVMODE será decorado com as configurações padrão e pode modificá-la em qualquer instância.
dm.dmPelsWidth = iWidth;
dm.dmPelsHeight = iHeight;
int iRet = User32.ChangeDisplaySettings(ref dm, User32.CDS_UPDATEREGISTRY);
O bloco de código fechado faz isso um pouco diferente de lidar com várias condições de erro. Gostaria de incentivá-lo a olhar para o arquivo fonte completo e ver o que ele faz. Isso é tudo que existe para isso.
Como proteger a resolução de tela do usuário
Finalmente, antes de continuarmos, é nossa responsabilidade salvaguardar a resolução de tela padrão de um usuário. Para fazer isso, você pode ter que usar alguns membros ou classes estáticas para manter a resolução da tela do usuário e retê-la quando concluir a execução.Bonus - O código-fonte completo
Fim de conversa, para ver o código-fonte de graça clica aqui.
Espero ter ajudado. Força!Resolução da tela com C#
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE1
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string
dmDeviceName;
public short
dmSpecVersion;
public short
dmDriverVersion;
public short dmSize;
public short
dmDriverExtra;
public int dmFields;
public short
dmOrientation;
public short
dmPaperSize;
public short
dmPaperLength;
public short
dmPaperWidth;
public short dmScale;
public short dmCopies;
public short
dmDefaultSource;
public short
dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short
dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dmFormName;
public short
dmLogPixels;
public short
dmBitsPerPel;
public int
dmPelsWidth;
public int
dmPelsHeight;
public int
dmDisplayFlags;
public int
dmDisplayFrequency;
public int
dmICMMethod;
public int
dmICMIntent;
public int
dmMediaType;
public int
dmDitherType;
public int
dmReserved1;
public int
dmReserved2;
public int
dmPanningWidth;
public int
dmPanningHeight;
};
class User_32
{
[DllImport("user32.dll")]
public static extern int
EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode);
[DllImport("user32.dll")]
public static extern int
ChangeDisplaySettings(ref DEVMODE1
devMode, int flags);
public const int ENUM_CURRENT_SETTINGS = -1;
public const int CDS_UPDATEREGISTRY = 0x01;
public const int CDS_TEST = 0x02;
public const int DISP_CHANGE_SUCCESSFUL = 0;
public const int DISP_CHANGE_RESTART = 1;
public const int DISP_CHANGE_FAILED = -1;
}
namespace Resolution
{
class CResolution
{
public CResolution(int a, int b)
{
Screen screen = Screen.PrimaryScreen;
int iWidth = a;
int iHeight = b;
DEVMODE1 dm = new DEVMODE1();
dm.dmDeviceName = new String(new char[32]);
dm.dmFormName = new String(new char[32]);
dm.dmSize = (short)Marshal.SizeOf(dm);
if (0 !=
User_32.EnumDisplaySettings(null,
User_32.ENUM_CURRENT_SETTINGS, ref dm))
{
dm.dmPelsWidth = iWidth;
dm.dmPelsHeight = iHeight;
int iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_TEST);
if (iRet == User_32.DISP_CHANGE_FAILED)
{
MessageBox.Show("Não é possível processar seu pedido");
MessageBox.Show("Descrição: Não é possível processar seu pedido. Desculpe
por esta Inconveniência. ", "Informação",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_UPDATEREGISTRY);
switch (iRet)
{
case User_32.DISP_CHANGE_SUCCESSFUL:
{
break;
// mudança bem sucedida
}
case User_32.DISP_CHANGE_RESTART:
{
MessageBox.Show("Descrição: Você precisa
reiniciar para que a mudança aconteça. \n Se você sentir qualquer problema após
a reinicialização da sua máquina \nEntão tente alterar a resolução no modo de
segurança. ", "Informação", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
// windows 9x series você tem que reiniciar
}
default:
{
MessageBox.Show("Descrição: Falha ao alterar
a resolução.", "Informação", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
// não conseguiu alterar
}
}
}
}
}
}
}
Pesquisar neste blogue
Com tecnologia do Blogger.