Wednesday, May 21, 2014

Usage of ObservableCollection class and INotifyCollectionChanged interface in WPF Data Binding

Usage of ObservableCollection class and INotifyCollectionChanged interface in WPF Data Binding

The ObservableCollection<T> is one of the most important features of WPF data binding. ObservableCollection is a generic dynamic data collection that provides notifications (using an interface "INotifyCollectionChanged") when items get added, removed, or when the whole collection is refreshed.

Namespace for ObservableCollection: System.Collections.ObjectModel

Syntax for ObservableCollection:

[SerializableAttribute]
public class ObservableCollection<T> : Collection<T>, 
INotifyCollectionChanged, INotifyPropertyChanged
ObservableCollection has a lot of properties, methods, events, explicit interface implementations. Get a complete list on MSDN.

Main feature of the ObservableCollection<T> are the events it raises when the items it contains change. When in your WPF application, you make any changes like remove/add/edit item in the ObservableCollection, the ObservableCollection updates the view controls to which it is binded because it internally implements INotifyCollectionChanged and INotifyPropertyChanged interfaces which are responsible for updating the view. INotifyCollectionChanged interface exposes the CollectionChanged event, an event that should be raised whenever the underlying collection changes.

INotifyCollectionChanged Interface: If you are using ObservableCollection, as I already mentioned, you don't need to implement INotifyCollectionChanged interface because it is already implemented in this class. But, if you want to use List instead of ObservableCollection, you will have to surely implement INotifyCollectionChanged if you want your view to get updated when any change is made to your List.

Implementation of INotifyCollectionChanged

public class ViewModelBase : INotifyCollectionChanged
{
  #region INotifyCollectionChanged
  public event NotifyCollectionChangedEventHandler CollectionChanged;
  private void OnNotifyCollectionChanged(NotifyCollectionChangedEventArgs args)
  {
    if (this.CollectionChanged != null)
    {
 this.CollectionChanged(this, args);
    }
  }
  #endregion INotifyCollectionChanged
}

Similarly,  Implementation of INotifyPropertyChanged

public class ViewModelBase : INotifyPropertyChanged
{
  #region INotifyPropertyChanged
  public event PropertyChangedEventHandler PropertyChanged;
  protected void OnPropertyChanged(string propertyName)
  {
    if (PropertyChanged != null)
 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  }
  #endregion INotifyPropertyChanged
}

You can inherit ViewModelBase class where you want to implement INotifyCollectionChanged and INotifyPropertyChanged interfaces.

ObservableCollection Example: 

I found a very good and simple example of ObservableCollection in WPF on CSharpCorner. Although, the author is not using MVVM pattern here for the sake of simplicity, you can convert this example to MVVM also.

Tuesday, May 20, 2014

Basics of WPF ICommand Interface in MVVM

Basics of WPF ICommand Interface in MVVM

I am going to cover basics of ICommand interface in WPF in MVVM pattern like syntax of ICommand interface, methods and events of ICommand interface, how to bind ICommand in View(XAML), how to implement ICommand interface in ViewModel etc. 

1. Namespace for ICommand

System.Windows.Input
Assembly: System

System.Windows.Input supports many Classes, Structures, Interfaces, Delegates and Enumerations. Here is the complete list on MSDN.

2. Methods exposed by ICommand

A) CanExecute: Defines the method that determines whether the command can execute in its current state. Typically, a command source calls the CanExecute method when the CanExecuteChanged event is raised.

Syntax: bool CanExecute(Object parameter)

Parameter: System.Object
Return Value: Boolean

B) Execute: Defines the method to be called when the command is invoked.

Syntax: void Execute(Object parameter)

Parameter: System.Object

3. Events exposed by ICommand

A) CanExecuteChanged: Occurs when changes occur that affect whether or not the command should execute.

Syntax: event EventHandler CanExecuteChanged

Implement the command by defining a class that implements ICommand and specifically implement the Execute method.

A complete ICommand Interface looks like:

public interface ICommand
{
  void Execute(object parameter);
  bool CanExecute(object parameter);
  event EventHandler CanExecuteChanged;
}

How to use ICommand in View (XAML)?

I am creating a Save button and binding ICommand to it.

<Button Content="Save" Command="{Binding SaveCommand}" CommandParameter="Hello"/>

CommandParameter: A parameter can be passed through the "CommandParameter" property. The CommandParameter is sent to both CanExecute and Execute events.

Further readings:


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.