Posts tonen met het label c#. Alle posts tonen
Posts tonen met het label c#. Alle posts tonen

maandag 24 november 2008

ASP.NET control voor FusionChart

Op de markt zijn talloze grafiek componenten aanwezig die in ASP.NET webapplicaties geïntegreerd kunnen worden. Persoonlijk zoek ik altijd naar freeware controls, omdat de vraag naar grafieken in een webapplicatie vaak niet van dergelijk belang is dat er (veel) geld voor neergeteld wordt.

Nu heb ik een oplossing gevonden welke gratis is, zeer dynamisch, flexibel... en het ziet er nog fraai uit ook. FusionCharts biedt een oplossing die op Flash (versie 8) gebaseerd is. Het grote voordeel van Flash is natuurlijk dat het cross-browser en cross-platform is. Het nadeel is dat het altijd op de computer van de gebruiker geïnstalleerd moet zijn om er gebruik van te kunnen maken.

Om het gebruik van deze functionaliteit te vereenvoudigen heb ik een ASP.NET (3.5) control ontwikkeld, welke de meest gebruikte functionaliteiten toepast. Het control maakt gebruik van Javascript om de Flash elementen op de pagina toe te voegen.
Een Visual Studio 2008 project kan hier gedownload worden. Dit project bevat het ASP.NET control en een testpagina.

Belangrijke eigenschappen van het control:

  • DataSource: het toekennen van data aan het Flash element geschiedt middels XML. Dit control biedt de mogelijkheid om een IEnumberable DataSource toe te kennen. Deze DataSource zal als XML in de pagina worden toegevoegd
  • DataMemberXAxis: DataMember uit de DataSource die op de X-as gebruikt moet worden
  • DataMemberYAxis: Lijst met één of meerdere DataMembers die op de Y-as gebruikt moet worden.
    Let op: indien er meer dan één DataMember wordt gebruikt, dan dient een correct ChartType toegekent te worden (alle ChartTypes die beginnen met 'MS' kunnen hiervoor worden gebruikt)
  • ChartType: type grafiek die gebruikt moet worden. Elk type maakt gebruik van een ander Flash bestand. Zie de FusionCharts folder in het VS2008 project

Succes ermee !

Bron(nen):
FusionCharts
FusionCharts Documentatie

ASP.NET control voor Google AJAX Search API

Google maakt het mogelijk om (redelijk) simpel hun zoekmachine functionaliteit te integreren in je eigen website. Hiervoor kan je gebruik maken van de Google AJAX Search API.

Deze API kan middels Javascript aangeroepen worden en biedt een AJAX zoekmachine in je eigen website. Om het gebruik van deze functionaliteit te vereenvoudigen heb ik een ASP.NET (3.5) control ontwikkeld, welke de meest gebruikte functionaliteiten van de API toepast.
Een Visual Studio 2008 project kan hier gedownload worden. Dit project bevat het ASP.NET control en een testpagina.

Belangrijke eigenschappen van het control:
  • GoogleApiKey: deze key kan hier worden opgevraagd
  • SearchDefinitions: dit is de lijst met de types Search die je kan integreren op je website. Zie de Google documentatie voor uitleg hiervan. Standaard is het type WebSearch al aanwezig (zie Constructor) in deze lijst.
  • MessageForNoResults: standaard wordt geen melding weergegeven indien Google geen zoekresultaten heeft. Middels deze eigenschap kan je toch een melding laten weergeven
  • NoDefaultCss: standaard voegt Google zelf HTML styles toe aan de Google elementen op je pagina. Wanneer je deze eigenschap op False zet wordt dit niet gedaan en kan je je eigen styles gebruiken (door je juiste class names in je stylesheet op te nemen).

Succes ermee!

Bron(nen):
Google AJAX Search API
Documentatie Google AJAX Search API

maandag 21 april 2008

Onoplosbaar probleem in Visual Studio 2008 (?)

Onderstaand probleem is opgelost met de hulp van Microsoft. Via Microsoft Connect heb ik een feedback ingelegd en daarin is het probleem opgelost. Hiervoor dien je het volgende te doen:
  1. Open de Visual Studio 2008 Command Prompt
  2. Voer het volgende commando uit: devenv.exe /ResetSkipPkgs
  3. Het probleem zou nu opgelost moeten zijn. Hierna kan Visual Studio weer via de normale weg opgestart worden



Momenteel heb ik een probleem in Microsoft Visual Studio 2008 dat ik niet opgelost krijg. De enige oplossing die ik nu nog zie is een herinstallatie van mijn PC. Dus als iemand nog ideeën heeft dan hoor ik ze graag !!!

Het probleem wat ik heb treedt op bij het aanmaken van een nieuw C# project of het openen van een bestaand C# project in Visual Studio 2008. Hierbij geeft VS2008 de volgende foutmelding terug en opent het C# project niet:
Project 'Business.Facade' could not be opened because the Microsoft Visual C# 2008 compiler could not be created. QueryService for '{7D960B16-7AF8-11D0-8E5E-00A0C911005A}' failed.
Bij een bestaand project ziet (een deel van) de Solution Explorer in VS2008 er als volgt uit:


Nadat ik met mijn rechtermuisknop op een project klik en de optie "Reload Project" selecteer, krijg in de volgende foutmelding:


Dit probleem treedt alleen op bij C# projecten (dus bijvoorbeeld niet bij Visual Basic projecten) en de geselecteerde versie van het .Net Framework (2.0, 3.0 of 3.5) maakt in dit geval niets uit.

Ik heb een 'Repair' van de VS2008 setup uitgevoerd. Hierna heb ik VS2008 compleet verwijderd en opnieuw geïnstalleerd, maar dit gaf allemaal geen resultaat.
Als iemand nog ideeën heeft, dan graag reageren op deze blog !!

maandag 4 februari 2008

Screen capture in C#

Screenshots of screen captures kunnen in C# gemaakt worden met behulp van een aantal API calls. Hieronder een stukje voorbeeldcode:

public const int SRCCOPY = 13369376;

[DllImport("user32.dll", EntryPoint = "GetDC")]
public static extern IntPtr GetDC(IntPtr ptr);

[DllImport("User32.dll")]
public static extern IntPtr GetDesktopWindow();

[DllImport("GDI32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

[DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
public static extern int GetSystemMetrics(int abc);

[DllImport("GDI32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);

[DllImport("GDI32.dll")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);

[DllImport("GDI32.dll")]
public static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);

[DllImport("GDI32.dll")]
public static extern bool DeleteDC(IntPtr hdc);

[DllImport("User32.dll")]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("GDI32.dll")]
public static extern bool DeleteObject(IntPtr hObject);


public static Bitmap CaptureScreen()
{
//In size variable we shall keep the size of the screen.
Point size = Point.Empty;

//Variable to keep the handle to bitmap.
IntPtr hBitmap;

//Here we get the handle to the desktop device context.
IntPtr hDC = GetDC(GetDesktopWindow());

//Here we make a compatible device context in memory for screen device context.
IntPtr hMemDC = CreateCompatibleDC(hDC);

//We pass SM_CXSCREEN constant to GetSystemMetrics to get the X coordinates of screen.
size.X = GetSystemMetrics(0);

//We pass SM_CYSCREEN constant to GetSystemMetrics to get the Y coordinates of screen.
size.Y = GetSystemMetrics(1);

//We create a compatible bitmap of screen size using screen device context.
hBitmap = CreateCompatibleBitmap(hDC, size.X, size.Y);

//As hBitmap is IntPtr we can not check it against null. For this purspose IntPtr.Zero is used.
if (hBitmap != IntPtr.Zero)
{
//Here we select the compatible bitmap in memeory device context and keeps the refrence to Old bitmap.
IntPtr hOld = (IntPtr)SelectObject(hMemDC, hBitmap);
//We copy the Bitmap to the memory device context.
BitBlt(hMemDC, 0, 0, size.X, size.Y, hDC, 0, 0, SRCCOPY);
//We select the old bitmap back to the memory device context.
SelectObject(hMemDC, hOld);
//We delete the memory device context.
DeleteDC(hMemDC);
//We release the screen device context.
ReleaseDC(GetDesktopWindow(), hDC);
//Image is created by Image bitmap handle and stored in local variable.
Bitmap bmp = Image.FromHbitmap(hBitmap);
//Release the memory to avoid memory leaks.
DeleteObject(hBitmap);
//This statement runs the garbage collector manually.
GC.Collect();
//Return the bitmap
return bmp;
}

//If hBitmap is null return null.
return null;
}

Hoe schakel je de 'X' knop van een Windows Form uit in C#

De sluitknop ('X' knop) van een Windows form kan je niet zomaar uitschakelen (disablen) in C#. Hiervoor dien je een aantal API calls uit te voeren. Hieronder een stukje voorbeeldcode:

private const int MF_BYPOSITION = 0x400;

[DllImport("user32.Dll")]
public static extern IntPtr RemoveMenu(IntPtr hMenu, int nPosition, int wFlags);

[DllImport("User32.Dll")]
public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

[DllImport("User32.Dll")]
public static extern IntPtr GetMenuItemCount(IntPtr hMenu);

/// <summary>
/// Disables the close button of a windows form
/// </summary>
/// <param name="hwnd">The handle of the form.</param>
public static void DisableCloseButton(IntPtr hwnd)
{
//Obtain the handle to the form's system menu
IntPtr menu = GetSystemMenu(hwnd, false);

// Get the count of the items in the system menu
IntPtr menuItemCount = GetMenuItemCount(menu);

// Remove the close menuitem
RemoveMenu(menu, menuItemCount.ToInt32() - 1, MF_BYPOSITION);
}

dinsdag 27 november 2007

Controleer in C# of je applicatie al draait

Om te controleren of er al een instantie van je C# applicatie draait kan je de Process collectie in de System.Diagnostics namespace controleren.
Hieronder de voorbeeld code:
/// 
/// Bepaal of een instantie van deze applicatie al draait
///

private static bool isPrevInstance()
{
try
{
//Bepaal de naam van het huidige proces
string currentProcessName = Process.GetCurrentProcess().ProcessName;
//Zoek naar de draaiende processen in dit systeem met deze naam
Process[] processesNamesCollection = Process.GetProcessesByName(currentProcessName);
//Bepaal of meer dan 1 proces draait
return (processesNamesCollection.Length > 1);
}
catch { }

return false;
}

maandag 19 november 2007

Verbergen van georven properties, methods of events van een klasse

Wanneer je een klasse in .Net erft, dan erf je ook automatsch alle properties, methods en events (members). Soms wil je dat een public member verborgen wordt voor de 'buitenwereld'. De IntelliSense zal de verborgen members dan niet in de lijst opnemen.
Het verbergen van zo'n member kan je op een aantal manieren doen:
  1. Verbergen in het properties venster van de designer.
    Hiervoor kan de attribuut System.Componentmodel.Browsable(bool browsable) gebruikt worden
  2. Verbergen voor IntelliSense.
    Hiervoor kan de attribuut System.Componentmodel.EditorBrowsable(EditorBrowsableState state) gebruikt worden
  3. Als Obsolete aanduiden, zodat de .Net compiler een waarschuwing of zelfs een foutmelding zal genereren.
    Hiervoor kan de attribuut System.Obsolete(string message, bool error) gebruikt worden

Bij veel members zijn de eerste twee attributen voldoende. De IntelliSense zal de members niet in de lijst opnemen, maar indien de member toch wordt aangeroepen zal de compiler de code nog wel accepteren.
Om de eerste twee attributen toe te kunnen passen dien je de member te overriden, bijv.:

public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
}
}


Bij sommige members zijn de eerste twee attributen niet voldoende en kan je ervoor kiezen om het derde attribuut te gebruiken. Hierbij zal de IntelliSense de member gewoon opnemen in de lijst, maar wordt wel aangeduid als [deprecated]. Indien je de error parameter van dit attribuut de waarde true meegeeft, zal de code door de compiler niet geaccepteerd worden.
Om het laatste attribuut toe te kunnen passen dien je het keyword new te gebruiken, bijv.:
public new string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
}
}

Bronnen:
Microsoft (System.Attribute derived classes)



donderdag 15 november 2007

Intressante informatie uit de StackTrace in .Net

Stack trace (ook wel stack backtrace of stack traceback genoemd) is een overzicht van actieve stack frames welke door een programma zijn uitgevoerd.
De StackTrace is bij de meeste .Net ontwikkelaars bekend als de extra debug informatie die het Exception object bevat.

De StackTrace is in .Net altijd op te vragen en kan (bijvoorbeeld ten behove van logging) handige informatie opleveren. Hiervoor kan het StackTrace object in de System.Diagnostics namespace gebruikt worden. Het nadeel van de informatie die je via de GetFrames() methode terugkrijgt, is dat dit veel te gedetailleerd is. Veel informatie over de interne calls binnen het .Net framework zelf, is hierin opgenomen. Om toch de relevante informatie uit de StackTrace te krijgen kan het controleren van de aanwezigheid van de FileName eigenschap van een StackFrame hulp bieden.
Hieronder de code die alleen deze relevante informatie uit de StackTrace haalt en in een string teruggeeft:

public static string GetStackTrace()
{
StringBuilder sb = new StringBuilder();
StackTrace stack = new StackTrace(true);

foreach (StackFrame frame in stack.GetFrames())
{
if (!string.IsNullOrEmpty(frame.GetFileName()))
sb.AppendFormat("{0}.{1} (line:{2} col:{3})\r\n",
frame.GetMethod().DeclaringType.FullName, frame.GetMethod().Name,
frame.GetFileLineNumber(), frame.GetFileColumnNumber());
}

return sb.ToString();
}



Bronnen:
WikiPedia
Microsoft

vrijdag 19 oktober 2007

Converteer afbeeldingen naar grijswaarden in .Net 2.0

Wanneer je in .Net afbeeldingen wil converteren naar grijswaarden, moet je GDI+ gebruiken. GDI (Graphics Device Interface) is hét component in het .Net framework wat gebruikt kan worden voor image processing.

Hieronder de code om afbeeldingen met behulp van GDI om te zetten naar afbeeldingen in grijswaarden:
public static Bitmap ConvertToGrayscale(Bitmap source, Color transparencyColor)
{
Bitmap bm = new Bitmap(source.Width, source.Height);
for (int y = 0; y < bm.Height; y++)
{
for (int x = 0; x < bm.Width; x++)
{
Color c = source.GetPixel(x, y);
int luma = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
bm.SetPixel(x, y, Color.FromArgb(luma, luma, luma));
}
}
if (transparencyColor!=Color.Empty)
bm.MakeTransparent(transparencyColor);
return bm;
}
public static Bitmap ConvertToGrayscale(Bitmap source)
{
return ConvertToGrayscale(source, Color.Empty);
}

De optionele parameter transparencyColor wordt gebruikt om deze kleur in de afbeelding te converteren naar Transparant!
Het grote nadeel van GDI+ is, is dat het niet erg snel is, omdat GDI+ nog niet voldoende gebruikt maakt van hardware acceleratie.

Een goed alternatief in het .Net 2.0 framework is de statische methode CreateDisabledImage in the ToolStripRenderer klasse. Deze methode heeft mij geholpen een groot aantal afbeeldingen in een User-Interface te converteren naar afbeeldingen in grijswaarden, met een hoge performance. Deze methode roep je als volgt aan:
public static Image CreateDisabledImage (
Image normalImage
)

Deze klasse is onderdeel van de System.Windows.Forms namespace. Je moet dus wel een reference naar deze assembly aan je project toevoegen.

Bronnen:
Wikipedia
Microsoft MSDN
Bob Powel (GDI guru)