Monday, 24 May 2010

Upload and download image in Silverlight and SQL server Application

We know image are store in database in binary format. In Silverlight application upload image in SQL and show it to Silverlight is pretty difference. In my project i failed complexity to perform that operation. My findings are describe step by step:

Step One:
In the .xaml file you should add following line.... inside tag <>

Image x:Name="empImage" Source = "{Binding path=BinaryData, Converter={StaticResource ConvertImage}}"

Here "empImage" is the name of Image control in .xaml. "BinaryData" is the binary array where binary data of image is kept after retrieving from database.

To convert the StaticResource you should create a UserControl link like :

"ImageSourceConverter" is a class where my image conversion is take place. So to make a link with that class file you should create a link like.

xmlns:local="clr-namespace:ImageHandler.Silverlight.Utility"

I kept it under Utility folder.

Code of ImageSourceConverter.cs file is:

public class ImageSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(new MemoryStream((Byte[])value));
return bitmap;
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}

}

Step Two:
In the .cs file, when you want to upload image in the database please paste the following code:

var ofdialog1 = new OpenFileDialog();
var result = ofdialog1.ShowDialog();
if (result.HasValue && result.Value)
{
var bi1 = new BitmapImage();
bi1.SetSource(ofdialog1.File.OpenRead());
empImage.Source = bi1;
}

Stream s = ofdialog1.File.OpenRead();
byte[] fileBytes = new byte[s.Length];

infoData.Photo = new Binary();
infoData.Photo.Bytes = fileBytes;

int byteCount = s.Read(fileBytes, 0, (int)s.Length);

s.Close();
s = null;

Step Three:

To show data in Silverlight Application write down the following code

ImageData imageData = new ImageData();
imageData.BinaryData = e.Result.Photo.Bytes;
empImage.DataContext = imageData;

"ImageData" is the class where i kept the BinaryData array as a property. Code of that class:

public class ImageData
{
public byte[] BinaryData { get; set; }
public BitmapImage BitmapImg { get; set; }
}

This is all about. Hope this will help you all to get rid off from the hassle of Image processing in Silverlight.

Strategy Pattern



The Strategy Pattern defines a family of algorithms, encapsulates each one and makes the interchangeable. Strategy lets the algorithm vary independently from clients that use it.

Design Principles
1.Identify the aspects of your application that vary and separate them from what stays the same.
2. Program to an interface, not an implementation.
3. Favor composition over inheritance (HAS-A can be better than IS-A).

Requirements:
SimUDuck Application: This is a duck pond simulation game. The game can show a large variety of duck species swimming and making quacking sounds.

Design:
The initial designers of the system used slandered OO techniques and created one Duck super class from which all other duck types inherit.

Problem faced:
It is becoming hard to manage the code when some new spec added. Client change or add new types of duck to the app. But to manage that we need to change all code from super class to sub class. There are some methods which does not have any effect of some class that also inherit to other class because of inheritance. Look at the figure 2. So here we go for Strategy Pattern.

Strategy Pattern:
According to design principle one describe above:
Take the parts that vary and encapsulate them, so that later you can alter or extend the parts that vary without affecting those don't.

We know that fly() and quack() are the parts of the Duck class that vary across ducks. To separate these behaviors from the Duck class, we'll pull both methods out of the Duck class and create a new set of classes to represent behavior. With our new design the duck subclass will will use a behavior represent by an interface (FlyBehavior and QuackBehavior) so the actual implementation of the behavior won't be locked into the Duck subclass.

According to design principle 2 describe above.
Programming to an implementation:

Dog d = new Dog();
d.bark();

Declaring the variable d as type Dog (a concrete implementation of animal) forces us to code to a concrete implementation.

Programming to an interface/supertype:

Animal animal = new Dog();
animal.makesound();

We know its a Dog but we can use the animal reference polymorphically. Look at the figure 1

FlyBehavior and QuackBehavior will change as per spec change so we have encapsulate them. If any new behavior comes we can just add that without editing the existing code. According to class diagram we can now write down the code as below:

// Duck super class.
public abstract class Duck
{
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck()
{
}
public abstract void display();
public void performFly()
{
flyBehavior.fly(); // Delegates to the behavior class.
}
public void performQuack()
{
quackBehavior.fly(); // Delegates to the behavior class.
}
public void swim()
{
System.out.println("All ducks float, even decoys!");
}
}

// Giving one subclass example here.
public class MallardDuck extends Duck
{
public MarllardDuck()
{
quackBehavior = new Quack(); // It use Quack class to handle its quack, so when performQuack is called, the responsibility for the quack is delegated to the Quack object and we get a real quack.

flyBehavior = new FlyWithWings();
}
public void display()
{
System.out.println("I'm a real Mallard duck");
}
}

// Interface and its implemented class.

public interface FlyBehavior
{
public void fly();
}
public class FlyWithWings implements FlyBehavior
{
public void fly()
{
System.out.println("I'm flying");
}
}
public class FlyNoWay implements FlyBehavior
{
public void fly()
{
System.out.println("I can't fly");
}
}

// Interface and its implemented class.

public interface QuackBehavior
{
public void quack();
}
public class Quack implements QuackBehavior
{
public void quack()
{
System.out.println("Quack");
}
}
public class MuteQuack implements QuackBehavior
{
public void quack()
{
System.out.println("Silence");
}
}
public class Squeak implements QuackBehavior
{
public void quack()
{
System.out.println("Squeak");
}
}

// Main method declaration

public class MiniDuckSimulator
{
public static void main(String[] args)
{
Duck mallard = new MallardDuck();
mallard.performQuack();
mallard .performFly();
}
}

Installer by Nullsoft Scriptable Install System


Tool: This is an open source tools. Which will give you an easy way to make your installer. NSIS software download link:

http://nsis.sourceforge.net/Download


How it is work: Basically this script will compress your exe, depended dlls, third party software’s, documents etc which is required to run your project. It will produce a single “Setup.exe” file. When you will install this setup file automatically it will write down everything in the computer registry to run your software properly. If you arrange your folder structure like depended dlls, exe, doc files etc. So it will be easy for you to upload that files during installer making.


IDE: There are some IDE to write down the script. But according to me “HM NSIS Edit 2.0.3” is the best one. It will provide you a wizard by clicking you can easily make your installer. Download link of that IDE:


http://www.mrtech.com/forums/index.php?PHPSESSID=0a1ef3d385a53f29fa4ede11669d6bed&topic=1090.msg2721#msg2721


You can choose options according to your requirement. After finishing your wizard you will get some script. But here I will explain some problem that I have faced:


1. When you select multiple language and its correspondence terms of service doc file. It was not working. So in the license page section write down the following line.


; License page

!insertmacro MUI_PAGE_LICENSE "$(MUILicense)"


2. If you want to install third party software you have to use the following code. You have to add it in a section.


Section 'name' SEC01

DetailPrint '..Installing name..'

;options

SetOutPath '$TEMP'

SetOverwrite on

;file work

File ".\path of software"

ExecWait 'MsiExec.exe /q /i $TEMP\Filename.msi' $0

DetailPrint '.. Name exit code = $0'

Delete '$TEMP\Filename.msi'

SectionEnd


I have added full code from my project here:

; Script generated by the HM NIS Edit Script Wizard.


; HM NIS Edit Wizard helper defines

!define PRODUCT_NAME "Application"

!define PRODUCT_VERSION "1.0"

!define PRODUCT_PUBLISHER "Application ApS"

!define PRODUCT_WEB_SITE "http://www.Application.dk"

!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\Application.exe"

!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"

!define PRODUCT_APP_REGKEY "Software\Application ApS\Application"

!define PRODUCT_UNINST_ROOT_KEY "HKLM"

!define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir"


; MUI 1.67 compatible ------

!include "MUI2.nsh"


; MUI Settings

!define MUI_ABORTWARNING

!define MUI_ICON ".\Application.ico"

!define MUI_UNICON ".\Application.ico"

!define MUI_TEXT_COLOR "FFFFFF"


; MUI Settings / Header

!define MUI_HEADERIMAGE

!define MUI_HEADERIMAGE_RIGHT

!define MUI_HEADERIMAGE_BITMAP ".\SB_Setupbar_Top.bmp"

!define MUI_HEADERIMAGE_UNBITMAP ".\SB_Setupbar_Top.bmp"

!define MUI_HEADER_TRANSPARENT_TEXT

; !define MUI_BGCOLOR "808080"


; MUI Settings / Wizard

!define MUI_WELCOMEFINISHPAGE_BITMAP ".\SB_Setupbar_Left.bmp"

!define MUI_UNWELCOMEFINISHPAGE_BITMAP ".\SB_Setupbar_Left.bmp"


; Language Selection Dialog Settings

!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"

!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"

!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"


; Welcome page

!insertmacro MUI_PAGE_WELCOME


; License page

!define MUI_LICENSEPAGE_RADIOBUTTONS

!insertmacro MUI_PAGE_LICENSE "$(MUILicense)"


; Directory page

!insertmacro MUI_PAGE_DIRECTORY

; Start menu page

var ICONS_GROUP

!define MUI_STARTMENUPAGE_NODISABLE

!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Application"

!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"

!define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"

!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}"

!insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP

; Instfiles page

!insertmacro MUI_PAGE_INSTFILES

; Finish page

!define MUI_FINISHPAGE_RUN "$INSTDIR\Application.exe"

!insertmacro MUI_PAGE_FINISH


; Uninstaller pages

!insertmacro MUI_UNPAGE_INSTFILES


; Language files

!insertmacro MUI_LANGUAGE "English"

!insertmacro MUI_LANGUAGE "Danish"


; License Language

LicenseLangString MUILicense ${LANG_ENGLISH} ".\SoftwareLicenseEnglish.rtf"

LicenseLangString MUILicense ${LANG_DANISH} ".\SoftwareLicenseDansk.rtf"


; MUI end ------


Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"

OutFile "Setup.exe"

;RequestExecutionLevel admin

InstallDir "$PROGRAMFILES\Application"

InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""

ShowInstDetails hide

ShowUnInstDetails hide


Function .onInit

!insertmacro MUI_LANGDLL_DISPLAY

FunctionEnd


Section 'RuntimeRequisite' SEC01

DetailPrint '..Installing RuntimeRequisite'

;options

SetOutPath '$TEMP'

SetOverwrite on

;file work

File ".\debug\RuntimeRequisite\RuntimeRequisite.msi"

ExecWait 'MsiExec.exe /q /i $TEMP\RuntimeRequisite.msi' $0

DetailPrint '..RuntimeRequisite exit code = $0'

Delete '$TEMP\RuntimeRequisite.msi'

SectionEnd


Section "Application" SEC02

SetOutPath "$INSTDIR"

SetOverwrite ifnewer


File ".\debug\QtCored4.dll"

File ".\debug\QtWebKitd4.dll"

File ".\Application.exe"

File ".\Application_en.qm"

File ".\Application_dk.qm"

SectionEnd

section Shortcut

; Shortcuts

SetShellVarContext all

!insertmacro MUI_STARTMENU_WRITE_BEGIN Application

SetOutPath "$INSTDIR"

CreateShortCut "$DESKTOP\Application.lnk" "$INSTDIR\Application.exe"

!insertmacro MUI_STARTMENU_WRITE_END

SectionEnd


Section -AdditionalIcons

SetShellVarContext all

!insertmacro MUI_STARTMENU_WRITE_BEGIN Application

WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"

CreateDirectory "$SMPROGRAMS\$ICONS_GROUP"

CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"

CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninst.exe"

CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Application.lnk" "$INSTDIR\Application.exe"

!insertmacro MUI_STARTMENU_WRITE_END

SectionEnd


Section -Post

WriteUninstaller "$INSTDIR\uninst.exe"

WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\Application.exe"

WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"

WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"

WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\Application.exe"

WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"

WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"

WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"

StrCmp $LANGUAGE ${LANG_DANISH} 0 english

WriteRegStr HKCU "${PRODUCT_APP_REGKEY}" "language" "danish"

Goto done

english:

StrCmp $LANGUAGE ${LANG_ENGLISH} 0 done

WriteRegStr HKCU "${PRODUCT_APP_REGKEY}" "language" "english"

done:

SectionEnd


Function un.onUninstSuccess

HideWindow

MessageBox MB_ICONINFORMATION|MB_OK "Application was successfully removed from your computer."

FunctionEnd


Function un.onInit

!insertmacro MUI_UNGETLANGUAGE

MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove Application and all of its components?" IDYES +2

Abort

FunctionEnd


Section Uninstall

SetShellVarContext all

!insertmacro MUI_STARTMENU_GETFOLDER "Application" $ICONS_GROUP

Delete "$INSTDIR\${PRODUCT_NAME}.url"

Delete "$INSTDIR\uninst.exe"

Delete "$INSTDIR\Application.exe"

Delete "$INSTDIR\ QtCored4.dll"

Delete "$INSTDIR\ QtWebKitd4dll"

RMDir /r "$INSTDIR\debug"

RMDir /r "$APPDATA\Application"


SetShellVarContext all

Delete "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk"

Delete "$SMPROGRAMS\$ICONS_GROUP\Website.lnk"

Delete "$DESKTOP\Application.lnk"

Delete "$SMPROGRAMS\$ICONS_GROUP\Application.lnk"

RMDir "$SMPROGRAMS\$ICONS_GROUP"

RMDir "$INSTDIR"


ExecWait 'MsiExec.exe /q /X{88164D59-4FFD-4874-93BC-5E001A7938F3}' $0

DetailPrint '..RuntimeRequisite exit code = $0'


DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"

DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"

DeleteRegKey HKEY_CURRENT_USER "Software\Application ApS"

SetAutoClose true

SectionEnd