Friday, October 26, 2012

A simple prize bond manager: old technology still works!

Introduction

The story begin with a simple problem, my father-in-law having some problem with his prize bonds. He has several prize bonds and each quarter government publish the prize bond lottery draw and he had to take each bond then go through the numbers. And it became hectic job for him.

Few days ago,  in a family dinner he told me about his problem, and asked me can I make a simple program so that his problem can be resolved. I kind of smiled and told him that I would be able to write something for him. Last weekend I sit and wrote some thing for him. Then I thought lets write an article about it, should be fun!.

My problems:

  1. It needs to be very simple.
  2. I can’t force him to use advance technology.
  3. Need to have some backup of data.
  4. Easy deployable.

It needs to be very simple

Decided to keep it very simple, so no login what so ever. One Main Screen where every thing is listed. A data add screen. And a simple match bond number screen to finding winning numbers. One interesting thing is that my father-in-law keep buying bonds for all the family members. so need to back up the data and ability to load backed up data.

I can’t force him to use advance technology

After little thought I decided to choose old technologies, because my client knows computer but i guess fancy advance technology might scare him off and my client will runway. And I believe it or not he use “windows xp” so what ever available with windows update.

Need to have some backup of data

Should be simple pretty simple steps to add delete and modify data. In case  user manage to screw thing up there should be a simple process with which he can backup the data and also restore data. Of course we have SQL Server and Enterprise manager to do that, but we don’t what clients to mange all those things. So I better use simple xml to generate back up.

Easy deployable

Important part, I don’t want to install anything in my pc beside the software, second the steps should be damn easy. kind of one client installer.

First thing First

Before writing any code I setup a open source project in github to keep my code. It’s a open source only because I want people to some how criticize me about my code and learn some thing out of it. Created my visual studio project. Now I have VS2012, and VS2010, I chose “VS2010” and as framework I chose “.net framework 2.0”.

Below the github project location is given. You guys can download and see what’s there if you want.

https://github.com/munnaonc/PrizeBondManager.git

Win forms 2.0 , .net framework 2.0 project

Alright, what ever I thought just gave me another shot to use some old technology, should be fun. After all the necessary code the solution explorer looks like the below screen shot.

image

Figure: Initial Project Structure in Solution explorer

To keep the data I have added a Microsoft SQL Server Compact Database also known as “.sdf” database named BondDB.sdf. Created a single table. In below screen shot the table structure is given.

image

Figure: Initial Project Structure in Solution explorer

For data retrieve and saving used one of the oldest technology that is typed dataset. Below screenshot gives you an idea of that work. In the dataset we have a custom query for the dataset named “GetDataBySerial” which returns the prize bond with serial number.

image

Figure: Initial Project Structure in Solution explorer

Wrapping Up the Coding

I added main feature as CRUD of Bonds, Backup Data, Load Data and of course Match a bond number, to find out if we have a winner or not. 

Without any user interface brush-up the application looks like the bellow screen shot. pretty bad right. We would make it presentable in future i guess, for the time being the idea is to get the application to my client quickly.

image

Figure: Main Application First Look

Data Layer codes for CRUD is given bellow

using System;
using System.Collections.Generic;
using System.Data;
using PrizeBonds.BondDBDataSetTableAdapters;

namespace PrizeBonds.Objects
{
public class DAL
{
public List<Bond> GetList()
{
var tBondTableAdapter = new t_bondTableAdapter();
var tBondDataTable = new BondDBDataSet.t_bondDataTable();
tBondTableAdapter.Fill(tBondDataTable);
var dataRows = tBondDataTable.Select();
return GetBonds(dataRows);
}

private static List<Bond> GetBonds(IEnumerable<DataRow> dataRows)
{
var bonds = new List<Bond>();
foreach (DataRow row in dataRows)
{
try
{
var bond = new Bond
{
Id = (Int64)row["ID"],
Serial = (Int64)row["Serial"],
Owner = row["Owner"].ToString(),
CreatedDate = (DateTime)row["CreatedDate"],
ModifiedDate = (DateTime)row["ModifiedDate"]
};
bonds.Add(bond);
}
catch (Exception exception)
{
exception.ToString();
}
}
return bonds;
}

public void AddBond(Bond bond)
{
var tBondTableAdapter = new t_bondTableAdapter();
tBondTableAdapter.Insert(bond.Serial, bond.Owner, bond.CreatedDate, bond.ModifiedDate);
}

public void DeleteBond(long id)
{
var tBondTableAdapter = new t_bondTableAdapter();
tBondTableAdapter.Delete(id);
}

public List<Bond> GetBondBySerial(long serial)
{
var tBondTableAdapter = new t_bondTableAdapter();
var bondDataTable = tBondTableAdapter.GetDataBySerial(serial);
if (bondDataTable.Rows.Count > 0)
{
return GetBonds(bondDataTable.Select());
}
return null;
}

public void UpdateBond(Bond bond)
{
var tBondTableAdapter = new t_bondTableAdapter();
var tBondDataTable = new BondDBDataSet.t_bondDataTable();
tBondTableAdapter.Fill(tBondDataTable);
var tBondRow = tBondDataTable.FindByID(bond.Id);
tBondRow.Owner = bond.Owner;
tBondRow.Serial = bond.Serial;
tBondRow.ModifiedDate = bond.ModifiedDate;
tBondTableAdapter.Update(tBondRow);
}
}
}


Created single object to manage and the application, named “bond”


using System;

namespace PrizeBonds.Objects
{
[Serializable]
public class Bond
{
public long Id { get; set; }
public long Serial { get; set; }
public string Owner { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
}
}


 


Add, Update and match Bond serial


Below a very simple Add Bond window code is given. Its a win form window with tool window border style and displayed as a modal dialog.


image


same window is displayed with some property modified, to update the data also.


public void SetData(Bond dataBoundItem)
{
_updateBondCandidate = dataBoundItem;
txtOwner.Text = _updateBondCandidate.Owner;
txtSerial.Text = _updateBondCandidate.Serial.ToString(CultureInfo.InvariantCulture);
}


below the update window is given.


image


Below match bond window is given.


image


Code for Add update bond



private void UpdateBond()
{
_updateBondCandidate.Owner = txtOwner.Text;
_updateBondCandidate.Serial = Convert.ToInt64(txtSerial.Text);
_updateBondCandidate.ModifiedDate = DateTime.Now;

var dal = new DAL();
dal.UpdateBond(_updateBondCandidate);
this.Close();
}

private void AddNewBond()
{
var bond = new Bond
{
Serial = Convert.ToInt64(txtSerial.Text),
Owner = txtOwner.Text,
CreatedDate = DateTime.Now,
ModifiedDate = DateTime.Now
};
var dal = new DAL();
dal.AddBond(bond);
this.Close();
}






code for match bond


private void btnMatchBond_Click(object sender, EventArgs e)
{
if (ValidData())
{
var dal = new DAL();
var bonds = dal.GetBondBySerial(Convert.ToInt64(txtSerial.Text));
if (bonds == null)
{
lblMessage.Text = @"No match found!";
lblMessage.ForeColor = System.Drawing.Color.Red;
}
else
{
lblMessage.Text = @"Success! match found! You are a winner!";
lblMessage.ForeColor = System.Drawing.Color.Green;
}
}
}


private bool ValidData()
{
if (string.IsNullOrEmpty(txtSerial.Text))
{
ShowValidSerialMessage();
return false;
}
char[] charArray = txtSerial.Text.ToCharArray();
foreach (var val in charArray)
{
if (char.IsDigit(val) == false)
{
ShowValidSerialMessage();
return false;
}
}
if (txtSerial.Text.Length != 7)
{
ShowValidSerialMessage();
return false;
}
return true;
}

private void ShowValidSerialMessage()
{
MessageBox.Show(@"Please enter 7 digit valid Prize Bond Serial");
txtSerial.Focus();
}

private void btnCancel_Click(object sender, EventArgs e)
{
Close();
}

private void txtSerial_KeyPress(object sender, KeyPressEventArgs e)
{
char keyChar = e.KeyChar;
if (keyChar.Equals('\r'))
{
btnMatchBond_Click(sender,new EventArgs());
}
}



Save and Load Bond Data


For saving and loading data used old serialization concept. Below the code for saving and loading bond data is given.


using System.Windows.Forms;

namespace PrizeBonds.Objects
{
public class BackUpManager
{
public void LoadRule()
{

// Configure open file dialog box
var dlg = new OpenFileDialog { FileName = "Prize Bond Manager",
DefaultExt = ".pbm", Filter = @"Prize Bond Manager Files (.pbm)|*.pbm" };

// Show open file dialog box
var result = dlg.ShowDialog();

// Process open file dialog box results
if (result == DialogResult.OK)
{
// Open document
var filename = dlg.FileName;
var serializer = new Serializer();
var deSerializeObject = serializer.DeSerializeObject(filename);
var bonds = deSerializeObject.Bonds;
var dal = new DAL();
foreach (var bond in bonds)
{
dal.AddBond(bond);
}
}
}

public void SaveRule()
{
var dal = new DAL();
var bonds = dal.GetList();
if (bonds.Count == 0)
{
const string message = @"You do not have any bonds to Save, thus I am unable "
+ @" to save any bonds. Please add some bonds before Saving";
MessageBox.Show(message);
return;
}

var dlg = new SaveFileDialog { FileName = "Prize Bond Manager",
DefaultExt = ".pbm", Filter = @"Prize Bond Manager Files (.pbm)|*.pbm" };

// Show save file dialog box
var result = dlg.ShowDialog();

// Process save file dialog box results
if (result == DialogResult.OK)
{
// Save document
string filename = dlg.FileName;
var serializer = new Serializer();
var objectToSerialize = new ObjectToSerialize { Bonds = bonds };
serializer.SerializeObject(filename, objectToSerialize);
}
}
}
}



In future release I would try to improve the look and field of the application. since the purpose of the application is only to match and keep data. And of course the application will be used only in once a month so investing huge time to make it more stunning won't be  a good idea., but still will invest some amount of time.


Conclusion


In this short article we have built a small application for managing prize bond with some of the old technology exists in ms world. Hope you would like it. Please drop comment if you like it and don’t forget suggest me improvement tips.

Friday, October 19, 2012

SDF Database: Re Create objects if you missed setting primary key as identity

I was developing a demo application, as database I chose to add “.sdf” local database file. I added some columns and set primary key. Some how I forgot to set the identity property of primary key.

Went back to the same interface and try to modify the table schema and set identity property. End up with the following error.

image

I thought setting some property for instance “Prevent Saving changes that require table re-creation. In Options->Database Tools-> Table and Database Designers will do the job.

image

But it didn’t, Later what I did is very bad and didn’t feel any good about it. I cleared the table. Deleted the old ID field. And re-create the same ID column with right property again.

I would appreciate if any body help me on this issue to edit a primary key identity property without deleting or clearing the data.

Friday, October 12, 2012

Asp.net: Required Field Validator with DropDownList

Today I want to share a very simple stuff That I learned while working, its kind of a silly learning, but hopefully will help someone someday. I want to make sure that a DropDownList is been selected before submitting a form. In asp.net we have a control for validation name “RequiredFieldValidator”, till now I have seen using this with only textbox. Below an example is given.

<asp:TextBox runat="server" ID="txtNumber" Width="200px"></asp:TextBox>
<asp:RequiredFieldValidator ForeColor="red" runat="server" ID="rfvNewTrackingNumber"
ControlToValidate="txtNumber" ErrorMessage="* Please type number">
</asp:RequiredFieldValidator>


But we can actually use this required field validator with DropDownList as well. Below another example is given for using with DropDownList


<asp:DropDownList runat="server" ID="ddlMethods" AppendDataBoundItems="True" Width="205px">
<asp:ListItem Value="0">Select Method</asp:ListItem>
</asp:DropDownList>
<asp:RequiredFieldValidator ForeColor="red" runat="server" ID="rfvNewMethod"
ControlToValidate="ddlMethods" ErrorMessage="* Please select method" InitialValue="0">
</asp:RequiredFieldValidator>



Note that in ListItem we have assigned Value=0 and in RequiredFieldValidator InitialValue=0 that is the main trick. If you have binding code in c# please make sure you also Set DataValueField.


Until next time.

Friday, October 5, 2012

ProjectName.xml in project folder. What? Why?

Looks like it’s a documentation related file. How I got this file? I converted a project from c# to vb.net. Conversion process worked pretty well. When I tried to check in the codes I keep seeing an un versioned file name [ProjectName].xml

At first I thought it’s a dll xml but later found out that its not necessary at all to run my project, I deleted it and build it again. works file but the file again got generated. Then looking at the build configuration I found the solution.

image

Its XML documentation file. To switch off the auto file creation all we have to do is uncheck the “XML Documentation file” checkbox of Build Tab of project configuration.

That’s it, the file will not get generated after you build again.