Thursday, April 30, 2009

C# - How to Serialize/Deserialize

As you know, when you want to send an object to another process, or transmit an object across the network (LAN, Intranet, WAN, Internet), you need to "serialize" the object. Serialization is the process of converting an object into a linear sequence of bytes and Deserialization is the process of converting a previously serialized sequence of bytes into an object.

Serialization has been a key part of .NET since version 1.0 and .NET Framework, implemented "Serialization" in the "System.Runtime.Serialization" namespace, and to serialize an object you can choose between, Binary, SOAP, XML, and custom serialization. There are libraries to serialize to special formats like comma delimited, etc ... too.


C# - How to Create a serializable (and deserializable) custom class
You need to add [Serializable] attribute to your class. The default handling of serialization, serialize all the members, including private members.
It's possible to customize and control serialization of your class depends on custom requirements either to improve efficiency.

C# - How to disable serialization of a member
Just add [NonSerialized] attribute in front of the specific member, it causes to exclude that member from serialized version of the object. sometimes, we need to reduce the size of our object to transfer it across the network then you can bypass calculable members and regenerate them all back in destination.

To enable your class to initialize the [NonSerialized] members automatically use OnDeserialization, this method will be called after deserializing is complete.


using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
...
private void btnSerialize_Click(object sender, EventArgs e)
{
string fName = @"C:\FB\Tst.data";
using (FileStream fs = new FileStream(fName, FileMode.Create))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, txt4Serialization.Text);
}
}

private void btnDeSerialize_Click(object sender, EventArgs e)
{
string fName = @"C:\FB\Tst.data";
using (FileStream fs = new FileStream(fName, FileMode.Open))
{
BinaryFormatter bf = new BinaryFormatter();
txtDeserialized.Text = (string)bf.Deserialize(fs);
}
}


Share/Bookmark

Monday, April 27, 2009

C# - How to have a reverse ordered Generic SortedList collection


The folowing code sample creates a generic SortedList using DateTimes as the keys and integers as the values.. The normal behavior of a generic SortedList collection is to sort the added items in ascending order but this example use generic IComparer to sort it in reverse order and the sample code show how to loop through the SortedList members (It's possible to loop by index too).

A System.Collections.Generic.IComparer to sort based on DateTime in reverse order:

...
using System.Collections;
using System.Collections.Generic;
...

public class DecendingDateCompare : IComparer
{
public int Compare(DateTime x, DateTime y)
{
return x.CompareTo(y) * -1;
}
}


A sample code to test:

...
using System.Collections;
using System.Collections.Generic;
...
SortedList aSortedList =
new SortedList(new DecendingDateCompare());

aSortedList.Add(DateTime.Now.AddDays(-10), 100);
aSortedList.Add(DateTime.Now.AddDays(10), 10);
aSortedList.Add(DateTime.Now.AddDays(-5), 90);
aSortedList.Add(DateTime.Now.AddDays(5), 20);
aSortedList.Add(DateTime.Now.AddDays(-3), 80);
aSortedList.Add(DateTime.Now.AddDays(3), 30);

StringBuilder sb = new StringBuilder();
IDictionaryEnumerator iDicEnum =
(IDictionaryEnumerator) aSortedList.GetEnumerator();

while( iDicEnum.MoveNext() )
sb.AppendLine( iDicEnum.Key.ToString() +
", " +
iDicEnum.Value.ToString() );

MessageBox.Show(sb.ToString());

Share/Bookmark

Friday, April 24, 2009

Regex - Expresso - winning regular expression development tool


Expresso is a free regular expression development tool. It's full-featured development environment for the experienced programmer who wants to code with knowledge of regular expressions and needs to test, analyze, and generate applicable and accurate regular expressions. Expresso code by Jim Hollenhorst.

It's an integrated regular expression editor, tester, analyzer with rich library of regular expressions ready to use for different categories.

To find out its features, look at the following link:
http://www.ultrapico.com/Expresso.htm

To download:
http://www.ultrapico.com/ExpressoDownload.htm

More links:

Expresso in www.codeproject.com
http://www.codeproject.com/KB/dotnet/expresso.aspx

The 30 Minute Regex Tutorial (by Jim Hollenhorst)
http://www.codeproject.com/KB/dotnet/regextutorial.aspx
Share/Bookmark

Wednesday, April 22, 2009

C# - A class to fade a Form

.Opacity property of form is a number between 0 and 1 (default), then if you change it from 1 to some lower values, you reduced the opacity. In the following sample, the formFader class contains a Static FormFaderWithStep method which accept the target form and another argument between 0 to 255 that show the number of steps which you want to fade your form base on it.


using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace tstBed
{
class formFader
{

public static void FormFaderWithStep(Form frm2Fade,
byte fadeNumOfSteps)
{
if ( (frm2Fade.Opacity != 1) || (fadeNumOfSteps < 1) )
return;
double fadeStep = frm2Fade.Opacity / fadeNumOfSteps;

for( byte iCntr = 0; iCntr < fadeNumOfSteps; iCntr ++ )
{
frm2Fade.Opacity -= fadeStep;
frm2Fade.Refresh();
}
}

}
}


Now just you need to find override version of Dispose event in your form designer code file for your form class (Example: form1.Designer.cs) and add a line to call the fader method, for example: formFader.FormFaderWithStep(this, 100);

protected override void Dispose(bool disposing)
{
formFader.FormFaderWithStep(this, 100);
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

Share/Bookmark

Tuesday, April 21, 2009

C# - A custom DataGridView class with always vertical scroll bar visible

Depend on the data which you want to show in a DataGridView, sometimes you need to keep vertical scroll bars always visible. If you don't have enough row to fill the DataGridView vertically, and you aligned and configured the columns' width for situations which data show with vertical scroll bar, then it's better to show the bar always.

The only thing which you need to do the job, is to set the VerticalScrollBar.Visible property to "true" in VisibleChanged event. I added dgvSetVerticalBar to fix the position of scroll bar, and it's necessary to call it in Load event of form which contains this custom DataGridView.


using System;
using System.Text;
using System.Windows.Forms;
using System.Collections.Generic;

namespace myNameSpace
{
public partial class myCustomDGV : DataGridView
{
public myCustomDGV()
{
// InitializeComponent();
this.VerticalScrollBar.Visible = true;
this.VerticalScrollBar.VisibleChanged +=
new EventHandler(VerticalScrollBar_VisibleChanged);

this.AllowUserToOrderColumns = false;
this.AllowUserToResizeColumns = false;
this.AllowUserToResizeRows = false;
this.RowHeadersVisible = false;
}

void VerticalScrollBar_VisibleChanged(object sender, EventArgs e)
{
this.VerticalScrollBar.Visible = true;
}

public void dgvSetVerticalBar()
{
this.VerticalScrollBar.SetBounds(
this.Width - this.VerticalScrollBar.Width - 1,
this.VerticalScrollBar.Location.Y + 1,
this.VerticalScrollBar.Width,
this.Height - 2);
}

}
}

Share/Bookmark

Monday, April 20, 2009

C# - DataGridViewColumn.SortMode

.SortMode Property is related to the sort mode for the column in DataGridView control.
http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcolumn.sortmode.aspx

....
Share/Bookmark

Sunday, April 19, 2009

Regex - Free sources about regular expressions


A very valuable source for regular expressions:
http://www.regexlib.com/

Regular expression cheat sheets:
http://regexlib.com/CheatSheet.aspx
OR
http://www.addedbytes.com/cheat-sheets/regular-expressions-cheat-sheet/
OR
http://opencompany.org/download/regex-cheatsheet.pdf
...
Share/Bookmark

Regex - Reformat a string by regular expressions

Sometimes we have strings with different formats but same meaning, then may be it's better to keep them all with an standard format in our report to keep consistency and make it easier for users.

One example is format of a phone number, the standard format can be considered as "(###) ###-####" and here we have a solution by regular expression even though that many different regular expressions would work.

Match m = Regex.Match(str,
@"^\(?(\d{3})\)?[\s\-]?(\d{3})\-?(\d{4})$" );
string newStr = String.Format("({0}) {1}-{2}",
m.Groups[1], m.Groups[2], m.Groups[3] );


In above regular expression pattern, each \d{n} part is surrounded by parenthesis which makes that part as a separate group (then each of items exists in Match.Groups array) that can be easily used using String.Format, another reformatting method is Regex.Replace, it's a static method and in the following example it replace dates in mm/dd/yy format to dd-mm-yy format:

string newStr = Regex.Replace(str,
@"\b(?\d{1,2})/(?\d{1,2})/(?\d{2,4})\b",
"${day}-${month}-${year}" );

In above pattern, ${day} inserts the substring captured by the group (?\d{1,2}) and so on.

Note: \b in above pattern specifies that the match must occur on a boundry between \w (alphanumeric) and \W (nonalphanumeric) characters. It means a word boundary, which are the first and last characters in words separated by any nonalphanumeric characters.
Share/Bookmark

Regex - String input validation by regular expressions

Using regular expression is one of the most efficient ways to bring security to validate user input. As an example, the following regular expression works to match valid names:

[a-zA-Z'-‘Ãâå\s]{1,40}
...
using System.Text.RegularExpressions;
...
Regex.IsMatch(s, @"^[a-zA-Z'-‘Ãâå\s]{1,40}$" )
...

Generally most input validation should be pessimistic and allow only input that consists entirely of approved characters. In this way, may user encounter with some restrictions but it helps to protect against malicious input such as SQL injection attacks.
Share/Bookmark

C# - How to bind a TextBox to a DataGridView column

The goal is "bind a TextBox to a column in a DataGridView control" to be able to edit the cell in that columns for each rows and also show the value of the cell in that column when user move through the grid rows.

In the following code, imagine that we have a DataGridView called dgvTst and a TextBox control that called txtTst. To bind, CellClick event of DataGridView is coded as following:

private void dgvTst_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (txtTst.DataBindings.Count > 0)
txtTst.DataBindings.RemoveAt(0);

// The code binds column index 2 to the TextBox control
txtTst.DataBindings.Add(
new Binding("Text", dgvTst[2, e.RowIndex], "Value", false) );
}


Share/Bookmark

Wednesday, April 15, 2009

Visual Studio - Is it possible to install both VS 2005 and VS 2008 on same machine?

Yes, it's possible to have both on same machine.

If you have multiple version of Visual Studio on your system, to open a solution, right click the file and select "Open With" from the context menu, then you see "Microsoft Visual Studio Version Selector", if you use it, the solution automatically opens with the correct version (2005 or 2008) and it's depend on the VS version which you created your solution.
Share/Bookmark

Monday, April 13, 2009

C# - A common question - Value-type vs Reference-type - Struct vs Class

Value types:
Simplest types in the .NET, they contain their data directly instead of containing a reference to the memory that stored the data. Instances of value types are stored in an area of memory called the "stack", it brings performance and minimal overhead to create, change, read, or remove them.

Three general value types:
- Built in types
(sbyte, byte, short, int, uint, long, float, double, decimal)
(char, bool, date)
- User-defined types
(structures - by "struct")
- Enumerations
(enum - symbols that have fixed values)

Structures:
You can define them by "struct" and simply they are stored on the stack and they contain their data directly. Structures are composite of other types. Structure can store multiple values and it can have methods, those methods usually works on values which are stored in the structure.

You should define a structure rather than a class, if the user defined type will perform better as a value type than a reference type. Generally structures meet all the following criteria:

* Represents a single value logically
* Has an instance size that is less than 16 bytes. (Interesting)
* Is not frequently changed after creation.
* Is not cast (Converting between types) to a reference type.

If you assign an structure to another one, it will copy data and changing value in each one, doesn't affect the values in another one cuz data of structures are stored in different places in "stack".

Question:
You pass a value type variable into a method as an arguments, the method changes the variable, when the method returns, the variable has not changed, why?
A: Passing a value type into a method, creates a copy of the data.

----------------------------------
Reference types:
Most types in .NET are reference types (a few thousand!). Reference types store the address of their data (like pointers). The actual data that the address refers is stored in an area of memory called the "heap". Garbage collection manages the memory used by the heap by disposing of items that are no longer referenced. Assigning a reference type to another doesn't copy the data because a reference type just directly store the address of data.

Class is a reference type.
C# struct/class Differences
Share/Bookmark

Saturday, April 11, 2009

C# - Control.Tag property


Share/Bookmark

Tuesday, April 7, 2009

C# - List.FindIndex Method

Searches for an element that matches the conditions
defined by the specified predicate, and returns the
zero-based index of the first occurrence within the
entire List<(Of <(T>)>).


List<T>.FindIndex Method (Predicate<T>)

Namespace: System.Collections.Generic
Assembly: mscorlib (in mscorlib.dll)

public int FindIndex(
Predicate<T> match
)



List<string> myLst = new List<string>();
...
// fill the list
...
int iIndx = 0;
if ( (iIndx = myLst.FindIndex(iIndx, StartWithEqualSign)) != -1 )
{
// Code for the row in the list which you found
}


// Search predicate returns true if a string starts with "=".
private static bool StartWithEqualSign(String s)
{
bool retVal = false;
if ( (s.Length > 0) && (s.Substring(0, 1) == "=") )
retVal = true;
return retVal;
}

Share/Bookmark

Monday, April 6, 2009

C# - ADO.NET - How to generate a DataTable based on table schema

In refer to another blog entry with title of
"Read table schema by SqlDataReader" in this weblog,
http://iborn2code.blogspot.com/2009/04/c-adonet-how-to-get-table-schema.html
now the following code shows how to use the
table schema to generate a DataTable based on
the schema:


DataTable retDtaTbl = new DataTable();

if (tblSchema.Rows.Count == 0)
return retDtaTbl;

tblSchema.DefaultView.Sort = "ColumnOrdinal";
foreach (DataRow rowSchema in tblSchema.Rows)
retDtaTbl.Columns.Add(
rowSchema["ColumnName"].ToString(),
System.Type.GetType( rowSchema["DataType"].ToString() ) );

Share/Bookmark

C# - ADO.NET - How to get Table Schema

Read table schema by SqlDataReader


DataTable tblSchemaDtaTbl = new DataTable();

#region Get table schema
try
{
using (SqlConnection sqlCn = new SqlConnection(sqlCnStr))
{
sqlCn.Open();
string sqlCmdStr = String.Format("SELECT * FROM {0}", tblName);
SqlCommand sqlCmd = new SqlCommand(sqlCmdStr, sqlCn);
SqlDataReader sqlDtaRdr = sqlCmd.ExecuteReader();
tblSchemaDtaTbl = sqlDtaRdr.GetSchemaTable();
sqlDtaRdr.Close();
}
}
catch (Exception ex)
{
MessageBox.Show( ex.Message, "Error!" );
}
#endregion

Share/Bookmark

Sunday, April 5, 2009

C# - Column name which contains spaces in DataTable.Compute

DataTable.Compute Method

Namespace: System.Data
Assembly: System.Data (in System.Data.dll)

public Object Compute(
string expression,
string filter
)

Return Value
Type: System..::.Object
An Object, set to the result of the computation.


Example - When you have a column name in your datatable which
contains space, you have to keep that name inside square brackets,
like [my column name]:


...
txtMyTextBox.Text =
myDtaTbl.Compute("SUM([my column name])", "").ToString();
...

Share/Bookmark

Saturday, April 4, 2009

C# - Convert byte[] to string by Encoding

A byte[] array is convertable to string using System.Text.Encoding class,
For this purpose there are other subclasses as follwoing too:

System.Text.ASCIIEncoding
System.Text.UnicodeEncoding
System.Text.UTF7Encoding
System.Text.UTF8Encoding

It's also possible to keep default encoding to get your string:


...
System.Text.Encoding myEnc = System.Text.Encoding.Default;
string strMacCmdPrm = myEnc.GetString( theByteArray );
...

Share/Bookmark

C# - UTF8/Base64 Encoder/Decoder

Base64
http://en.wikipedia.org/wiki/Base64

class fbBase64
{
public static string EncodeToBase64(string theString)
{
return Convert.ToBase64String(
System.Text.Encoding.UTF8.GetBytes(theString));
}

public static string DecodeBase64(string theString)
{
return System.Text.Encoding.UTF8.GetString(
Convert.FromBase64String(theString));
}
}

Share/Bookmark

Friday, April 3, 2009

SQL - Yet another thing about checking existence of a table in a MS SQL database

- The first method is checking specific table in sysobjects with
'U' value for xtype column which shows the object is a [user table].

USE AclMacGen
GO
IF EXISTS (
SELECT *
FROM sysobjects
WHERE
id = OBJECT_ID('[myDB].[dbo].[myTable]')
AND xtype = 'U'
)
BEGIN
SELECT 'It is EXIST'
END


- The second way is just by checking availability of specific
table as an object in the database.

IF OBJECT_ID('[myDB].[dbo].[myTable]') IS NOT NULL
BEGIN
SELECT 'It is EXIST'
END

Share/Bookmark

MS SQL tinyint, smallint, int, and bigint datatypes and equivalent in C#

First let's take a look at data range for int datatypes in MS SQL:


Datatype Range Storage
-------- ------_---------------------------- -------
bigint -2^63 (-9,223,372,036,854,775,808)
TO 8 bytes
2^63-1 (9,223,372,036,854,775,807)

int -2^31 (-2,147,483,648)
TO 4 bytes
2^31-1 (2,147,483,647)

smallint -2^15 (-32,768)
TO 2 bytes
2^15-1 (32,767)

tinyint 0 to 255 1 bytes


Then we have the following data conversion table too:


SQLServer Type SQL-92 Compliant Type C# Type CLS-Compliant Type
--------- -------------------------- ------- ------------------
bigint bigint long Int64
int integer int Int32
smallint smallint short Int16
tinyint tinyint byte Byte

Now we can find trhat if you have a column in tinyint datatype
and you want to get its value by a SqlDataReader, the method
which will work for you would be .GetByte( iClmnIndx )


public bool getMyTinyIntValue()
{
bool retVal = true;
int iTinyIntVal = 0;

using (SqlConnection sqlCn = new SqlConnection(sqlCnStr))
{
try
{
string strSqlCmd = "SELECT iTinyInt FROM myTable";

SqlCommand sqlCmd = new SqlCommand(strSqlCmd, sqlCn);
sqlCn.Open();

SqlDataReader sqlDtaRdr = sqlCmd.ExecuteReader();
if (sqlDtaRdr.Read())
iTinyIntVal = sqlDtaRdr.GetByte(0);
else retVal = false;

sqlDtaRdr.Close();
sqlCn.Close();
}
catch (Exception ex)
{
retVal = false;
MessageBox.Show(ex.ToString(),
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
finally
{
if (sqlCn != null) sqlCn.Close(); // Close the connection
}
return retVal;
}
}

Share/Bookmark

Thursday, April 2, 2009

SQL - Case sensitive varchar columns comparison


Share/Bookmark