Saturday, May 17, 2014

DataBinding in WPF using DataContext in XAML

DataBinding in WPF using DataContext in XAML

I would like to share a very simple example of databinding in WPF using DataContext in XAML file. In this WPF databinding simple example, I have a class named EmpViewModel which has two properties EmpID and EmpName. I will bind these EmpID and EmpName properties with two textboxes in the XAML file. Following is my EmpViewModel class under SampleApplication namespace:

EmpViewModel.cs

namespace SampleApplication
{
     public class EmpViewModel
    {
        private int empID;
        public int EmpID
        {
            get
            {
                return 123;
            }
            set
            {
                empID = value;
            }
        }
        
        private string empName;
        public string EmpName
        {
            get
            {
                return "ABC";
            }
            set
            {
                empName = value;
            }
        }
    }
}

After this class, I have following XAML file(MainWindow.xaml) which contains two textboxes to which I want to bind the EmpID and EmpName properties.

MainWindow.xaml

<Window x:Class="SampleApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>       
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="200" />
        </Grid.ColumnDefinitions>
        
        <Label Grid.Row="0" Grid.Column="0" Content="ID:"/>
        <Label Grid.Row="1" Grid.Column="0" Content="Name:"/>
        <TextBox Grid.Column="1" Grid.Row="0" Text="" />
        <TextBox Grid.Column="1" Grid.Row="1" Text="" /> 
    </Grid>
</Window>

I will have to make some changes/additions to this XAML file to bind the EmpID and EmpName properties to the above textboxes. 

1. First of all, I will have to add a xaml namespace like following:

xmlns:local="clr-namespace:SampleApplication"

2. Now, I have to add DataContext:

<Window.DataContext>
<local:EmpViewModel />
</Window.DataContext>

3. Finally, I have to bind properties to the textboxes:

<TextBox Grid.Column="1" Grid.Row="0" Text="{Binding EmpID}" />
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding EmpName}" /> 

My final xaml will look like this:

MainWindow.xaml

<Window x:Class="SampleApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleApplication"
        Title="MainWindow" Height="350" Width="525">

   <Window.DataContext>
        <local:EmpViewModel />
    </Window.DataContext>

    <Grid>       
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="200" />
        </Grid.ColumnDefinitions>
        
        <Label Grid.Row="0" Grid.Column="0" Content="ID:"/>
        <Label Grid.Row="1" Grid.Column="0" Content="Name:"/>
        <TextBox Grid.Column="1" Grid.Row="0" Text="{Binding EmpID}" />
        <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding EmpName}" /> 
    </Grid>
</Window>

Friday, May 16, 2014

Delphi Coding Standards and Guidelines

Delphi Coding Standards and Guidelines

Below are some Delphi coding standards and guidelines mentioned which each Delphi developer should take care of. Anybody can code, but neat and clean coding is an art. I have tried to mention some Delphi coding standards and guidelines which I follow everyday. Following list includes use of proper naming convention and indentation, proper exception handling and resource management, usage of proper datatypes etc.

1. Use proper naming convention

Use proper naming conventions and provide meaningful names to classes, records, arrays, enumerated types, pointers and other variables so that code readability is maintained and other developers can easily understand your code.

2. Always maintain a clear indentation

Always leave two character spaces before writing the child statement. Here is the example.

if condition1 then
begin
    fist statement
    second statement
end;

3. Declare records/class names prefixed with 'T' character, pointer names prefixed with 'P' character and field names of the class should be prefixed with 'F' character. The name of the object of the class should be same as that of the class name except the 'T' character prefixed. Here is the example.

TMyRecord = record
    ID : integer;
    RecNo : integer
end;

TMyClass = class(TObject)
private
   FMyField1: Integer;
   FMyField2: Integer;
end;

MyClass = TMyClass;

PMyPointer = ^TMyClass;

4. Always use try/except and try/finally

Always use try/except to handle all kinds of exception which may be raised from your code. Always use try/finally to free up memory which you might have assigned in your code. 

5. Avoid the use nested "with" statement

Nested "with" statements are confusing and make the debugging very hard. It decreases the code readablility. Consider the following example.

with myQueryComponent do             
begin 
    .......
    .......
  with myQueryComponent2 do
  begin
  ......
......
  end;
end;

6. Try to avoid "exit" statement

Wherever possible, try to minimize the use of "exit" statement. When dealing with loops, try to end the loop with some condition and avoid the use of exit statement.

7. "case" statements should be neat and clean

When you are using "case" statements, try to keep less code in it. If your code grows in size, it is advisable to make a different procedure or function for it and just call that function/procedure.

8. Try to minimize the use of variants

Variants are commonly used when datatypes are generally unknown but as a responsible developer you must try to avoid its usage. Consider the following example.

with dsMyDataset do
begin
    Active := False;
    Params.ParamByName('ID').AsVariant := AnyID;
    Active := True;
end;

Here, if you know that AnyID variable will be integer in all cases, then you should avoid the use of "AsVariant" like following:

with dsMyDataset do
begin
    Active := False;
    Params.ParamByName('ID').AsInteger := AnyID;
    Active := True;
end;

9. Minimize the use of global variables

Always try to use less global variables in your unit and try to declare them locally where you want to use them.

Tuesday, May 13, 2014

How to Insert/Edit Rows in Firebird Dataset in Delphi using FIBPLUS Components?

How to Insert/Edit Rows in Firebird Dataset in Delphi using FIBPLUS Components?

You can insert a row and edit an existing row in firebird dataset in Delphi. I will use FIBPLUS dataset component in Delphi XE4. Just use Insert and Edit procedures for this purpose. First of all create a dataset of type TpFIBDataset. Lets have a look at this very simple example.

var
dsMyFirebirdDataset : TpFIBDataset;

Insert a row in a dataset

with dsMyFirebirdDataset do
begin
Insert;
dsMyFirebirdDatasetID.AsInteger := 101;
dsMyFirebirdDatasetDESC.AsString := 'Hello';
Post;
end;

You can also use FieldByName like following:

with dsMyFirebirdDataset do
begin
Insert;
FieldByName('ID').AsInteger := 101;
FieldByName('DESC').AsString := 'Hello';
Post;
end;

Similarly, you can edit a record/row in the dataset like following:

Edit a row in a dataset

With dsMyFirebirdDataset do
begin
Edit;
dsHdwPriceGroupDESC.AsString := 'Hello World';
Post;
end;

or

With dsMyFirebirdDataset do
begin
Edit;
FieldByName('DESC').AsString := 'Hello World';
Post;
end;

Friday, May 9, 2014

How to populate data into dataset from Firebird database in Delphi using FIBPLUS components?

How to populate data into dataset from Firebird database in Delphi using FIBPLUS components?

I am using Firebird 2.5.2 database and Delphi XE4. I will be using FIBPlus TpFIBDatabase and TpFIBDataset components to populate data from Firebird database to dataset in Delphi XE4. For this, you have to drag TpFIBDatabase and TpFIBDataset components into your Delphi Form from the Tool Palette. Set various properties of TpFIBDatabase component like DBName, Username, Password and LibraryName to connect to Firebird database. I have written a complete tutorial on this. After successfully creating the database connection, set following properties of TpFIBDataset component:

Database: Provide the name of database component (TpFIBDatabase) in Database property. In my case, I have created dbMyDatabase component in my previous article.

SQLs: Write the query which you want to run. In my case, I am running following query:

SELECT ID, NAME FROM MY_FIREBIRD_TABLE WHERE ID = :ID AND NAME = :NAME;

Now, populate your dataset like this:

var
dsMyDataSet : TpFIBDataSet;

with dsMyDataSet do
begin
  Active := False;
  Params.ParamByName('ID').AsInteger := 1000;
  Params.ParamByName('NAME').AsString := 'Naresh';
  Active := True;
  RecordCount;
end;

Note: You can also set Database and SQLs properties in pas file as following:

with dsMyDataSet do
begin
  Active := False;
  Database := dbMyDatabase;
  SQLs.SelectSQL.Text := 'SELECT ID, NAME FROM MY_FIREBIRD_TABLE WHERE ID =:ID                                               AND NAME = :NAME;';
  Params.ParamByName('ID').AsInteger := 1000;
  Params.ParamByName('NAME').AsString := 'Naresh';
  Active := True;
  RecordCount;
end;

How to create database connection with Firebird in Delphi using FIBPLUS components?

How to create database connection with Firebird in Delphi using FIBPLUS components?

I am using Firebird 2.5.2 with Delphi XE4. I will show you how to create a database connection with Firebird database in Delphi XE4 using FIBPLUS component? Just go into the Tool Palette and search for TpFIBDatabase component under FIBPLUS. Drag it into the form and name it. I have given "dbMyDatabase" name to TpFIBDatabase database component. If you see your pas file, a declaration for TpFIBDatabase will look like this:

var
dbMyDatabase: TpFIBDatabase;

Now create a function "ConnectToDatabae" with return type boolean. This function will return true if Firebird database connection is established successfully otherwise false.

function TMyForm.ConnectToDatabase : boolean; 
begin
  result := False;
  try
    try
      with dbMyDatabase do
     begin
        DBName := 'C:\MyProject\MyDB.FDB';
ConnectParams.UserName := 'SYSDBA';
ConnectParams.Password := 'masterkey';
LibraryName := 'C:\Program Files(86)\Firebird\Firebird_2_5\bin\fbclient.dll'; 
Connected := True;
     end;
     result := True;
    except
`     result := False;
end;
  finally
    dbMyDatabase.Connected := False;
  end;
end;

In the above function, I have set different properties of TpFIBDatabase component like DBName, Username, Password, LibraryName etc as following:

DBName := 'C:\MyProject\MyDB.FDB'; //MyDB is the firebird database name
ConnectParams.UserName := 'SYSDBA'; //Default username of firebird database
ConnectParams.Password := 'masterkey'; //Default password of firebird database
LibraryName := 'C:\Program Files(86)\Firebird\Firebird_2_5\bin\fbclient.dll'; //Default library path of firebird database

Note: You can set all these properties at design time in your dfm file. But I would recommend to write all these settings in your pas file.

After setting the above properties, I have set connected property to true. If Firebird database connection is established successfully, above function will return true otherwise false. Finally, I am disconnecting the database.

Friday, April 11, 2014

How to use Javascript localStorage to retain values of HTML input elements on Page Refresh?

How to use Javascript localStorage to retain values of HTML input elements on Page Refresh?

localStorage in Javascript is used to retain the values of the HTML input elements on the page refresh. setItem() and getItem() methods are used to set and get the data from the localStorage. clear() method is used to clear the data from the localStorage.

Suppose I have following 2 textboxes and buttons in my HTML page. 

<input type="text" id="text1" value="" />
<button type="button" id="myButton1" onclick="myButtonClicked('text1')">Click Me</button>

<input type="text" id="text2" value="" />
<button type="button" id="myButton2" onclick="myButtonClicked('text2')">Click Me</button>

I fill some data in each textbox. Now when I refresh the page, the data is lost. I want to retain that data on the page refresh. I will use localStorage for this purpose. 

//Store values on button click
function myButtonClicked(id)
{
var aLocalStorage = [];
if(localStorage.getItem('myLocalStorage') != null)
{
aLocalStorage = JSON.parse(localStorage.getItem('myLocalStorage'));
//get stored item from localStorage by json parsing
}
    aLocalStorage.push(id);
    aLocalStorage.push(document.getElementById(id).value);
    localStorage.setItem('myLocalStorage', JSON.stringify(aLocalStorage));
    //stored the entered element id and value in localStorage by doing stringify
}

Now when the page is refresh, call the following function on $(Idocument).ready event like this

$(document).ready(function()
{
retainValues();
});

function retainValues()
{
if(localStorage.getItem('myLocalStorage') != null)
{
var aLocalStorage =[];
aLocalStorage = JSON.parse(localStorage.getItem('myLocalStorage'));

var i = 0;
while (i < aLocalStorage.length)
{   
if (document.getElementById(aLocalStorage[i]) != null)
{
document.getElementById(aLocalStorage[i]).value = shoppingCartList[i+1];
}
i = i + 2;
}
}
}

How to call both Javascript function with PHP file on the click on HTML link?

How to call both Javascript function with PHP file on the click on HTML link?

Recently, I was trying to implement logout functionality while working with PHP website. I had put logout logic in logout.php file and I was calling that file on the click of logout link like following:

<a href="logout.php">Logout</a>

This was working fine. But later on I realised that I also have to clear localstorage maintained by using Javascript before logging out the user. So, I had to call the javascript function that clears the localstorage before calling the logout.php file. 

Javascript function for clearing the localstorage:

function ClearMyLocalStorage()
{
localStorage.clear();
}

I investigated two approaches to accomplish my task.

Approach 1:

<a href="logout.php" onclick="ClearMyLocalStorage()">

Approach 2:

<a href="javascript:;" onclick="ClearMyLocalStorage();">Logout</a>

And in your function you have to write like

function ClearMyLocalStorage()
{
    localStorage.clear();
    window.location.href = 'logout.php';
}