// Add these to the class
private static int instanceId = 1;
private int instance = 1;
// Call this within the contructor
public SetObjectInstance(...)
{
instance = instanceId;
instanceId++;
Debug.WriteLine("XXX instance \'" +
instance.ToString() + "\' constructed");
}
// Within the finalizer OR if the object does not have a Finalizer add one
~XXX()
{
Debug.WriteLine("XXX instance \'" + instance.ToString() +
"\' finalized");
}
December 2, 2007
Pattern for Detecting Object Leaks
A simple method
Deploying Unmanaged DLLs
Found this neat trick here
Nice idea. Tried it and it works.
Heres my version of the resource extractor:
public static class ResourceExtractor
{
public static void ExtractResourceToFile(
string resourceName,
string filename)
{
if (System.IO.File.Exists(filename))
{
System.IO.File.Delete(filename);
}
if (!System.IO.File.Exists(filename))
{
using (System.IO.Stream s = System.Reflection.Assembly.
GetExecutingAssembly().GetManifestResourceStream(resourceName))
{
using (System.IO.FileStream fs = new System.IO.
FileStream(filename, System.IO.FileMode.Create))
{
byte[] b = new byte[s.Length];
s.Read(b, 0, b.Length);
fs.Write(b, 0, b.Length);
}
}
}
}
}
November 25, 2007
Using HelpRequested
The following will get help related to the control which has the mouse over it by pressing the F1 button
this.HelpRequested += new HelpEventHandler(this.XXXDialog_HelpHandler);
...
private void XXXDialog_HelpHandler(
object sender, HelpEventArgs helpEvent)
{
if (helpEventHandler != null)
{
Point pt = this.PointToControl(e.MousePos);
Control control = this.GetChildAtPoint(pt);
GetHelpOn(control);
helpEvent.Handled = true;
}
}
CultureInfo, DateSeparator and TimeSeparator
CultureInfo ci = new CultureInfo("de-DE");
string dateSep = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator;
string timeSep = CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator;
Using the Params keyword
string[] ReplaceInStrings(char oldchar, char newchar, params string[] src)
{
string[] res = new string[src.Length];
int ix = 0;
foreach (string targ in src)
{
res[ix++] = targ.Replace(oldchar, newchar);
}
return res;
}
The nice thing about the use of the 'params' keyword is that it can take an array parameter directly or a series of the specified type. It can even work with no parameters of the specified type. The following code demonstrates this behaviour
private void ParamsTest()
{
string[] res;
string[] strings = new string[] { "Some_string", "Another_string"};
// Pass an array directly
res = ReplaceInStrings('_', ' ', strings);
// Pass a series of objects of the specified type, this is automatically
// converted to an array
res = ReplaceInStrings('_', ' ', "This_string", "That_string", "Unchanged");
// Pass a single object of the specified type
res = ReplaceInStrings('_', ' ', "A_Single_string");
// Pass NO objects of the specified type!
// This still works an empty array is passed into the routine
res = ReplaceInStrings('_', ' ');
}
can it be used on a remoting interface?
Flags Based Enumerated Types
An extension class that extends a flag based enumerated type with set/group theory type operations. See FileAttributesExtender for a usage of this class.
public partial class EnumFlagsForm : Form
{
[Flags]
public enum EnumFlags
{
None = 0,
Emergency_Stop = 0x1,
Greasey = 0x2,
Spot_Spot = 0x4,
Doughnuts = 0x8,
Lift_Moving = 0x10,
Doors_Open = 0x20,
Forbidden = 0x40
}
//SourceTypes sourceTypes;
public static class EnumFlagsExtender
{
// Return lhs flags plus rhs flags
public static EnumFlags Union(this EnumFlags lhs, EnumFlags rhs)
{
return lhs | rhs;
}
// Return flags common to lhs and rhs
public static EnumFlags Intersection(this EnumFlags lhs, EnumFlags rhs)
{
return lhs & rhs;
}
// Return lhs flags minus rhs flags
public static EnumFlags Subtract(this EnumFlags lhs, EnumFlags rhs)
{
EnumFlags common = lhs & rhs;
int res = (int)lhs - (int)common;
return (EnumFlags)(res);
}
// Return true if lhs contains all the flags within rhs
public static bool Contains(this EnumFlags lhs, EnumFlags rhs)
{
EnumFlags common = lhs & rhs;
return (common == rhs);
}
// Return true if lhs contains one of the flags within rhs
public static bool ContainsOneOf(this EnumFlags lhs, EnumFlags rhs)
{
EnumFlags common = lhs & rhs;
return ((int)common > 0);
}
// NON-extension methods here
public static EnumFlags FromString(string source)
{
EnumFlags res = (EnumFlags)Enum.Parse(typeof(EnumFlags), source, true);
return res;
}
}
public void Test1()
{
EnumFlags test = EnumFlags.Lift_Moving |
EnumFlags.Doors_Open | EnumFlags.Doughnuts;
string str = test.ToString();
//str = str.Replace('_', ' ');
Debug.WriteLine(str);
EnumFlags newtest = EnumFlagsExtender.FromString(str);
Debug.Assert(newtest == test);
}
public void EnumFlagsSubtractTest()
{
EnumFlags test1 = EnumFlags.Lift_Moving | EnumFlags.Doors_Open |
EnumFlags.Doughnuts | EnumFlags.Emergency_Stop;
EnumFlags test2 = EnumFlags.Lift_Moving | EnumFlags.Forbidden |
EnumFlags.Emergency_Stop;
EnumFlags expected = EnumFlags.Doors_Open | EnumFlags.Doughnuts;
EnumFlags outcome = test1.Subtract(test2);
Debug.Assert(outcome == expected);
expected = EnumFlags.Doors_Open | EnumFlags.Doughnuts | EnumFlags.Greasey;
outcome = outcome.Union(EnumFlags.Greasey);
Debug.Assert(outcome == expected);
EnumFlags test3 = EnumFlags.Doughnuts | EnumFlags.Greasey;
bool res = outcome.Contains(test3);
Debug.Assert(res);
res = outcome.Contains(EnumFlags.Lift_Moving | EnumFlags.Forbidden);
Debug.Assert(!res);
}
public EnumFlagsForm()
{
InitializeComponent();
lbSourceTypes.Items.AddRange(
UnderscoresToSpaces(
Enum.GetNames(typeof(EnumFlags))));
OnSelectedValueChanged(this, null);
}
string[] UnderscoresToSpaces(string[] src)
{
return ReplaceInStrings('_', ' ', src);
}
string[] SpacesToUnderscores(string[] src)
{
return ReplaceInStrings('_', ' ', src);
}
string SpacesToUnderscores(string src)
{
return src.Replace(' ', '_');
}
string[] ReplaceInStrings(char oldchar, char newchar, params string[] src)
{
string[] res = new string[src.Length];
int ix = 0;
foreach (string targ in src)
{
res[ix++] = targ.Replace(oldchar, newchar);
}
return res;
}
private void OnSelectedValueChanged(object sender, EventArgs e)
{
EnumFlags test = EnumFlags.None;
foreach (string type in lbSourceTypes.SelectedItems)
{
test = EnumFlagsHelper.Add(test,
EnumFlagsHelper.FromString(SpacesToUnderscores(type)));
}
tbSelected.Text = test.ToString();
lblIsAudioAndVideo.Text = "WoopsTest() == " +
(EnumFlagsHelper.WoopsTest(test)).ToString();
}
private void butTest_Click(object sender, EventArgs e)
{
Test1();
EnumFlagsSubtractTest();
}
}
Here is a visual studio code snippet for the enum extender<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header><Title>Flags Enum Extender pattern</Title>
<Description>Implement an extender for a 'Flags' type Enum. The extender adds set type methods to the enumertaion type</Description>
<Keywords>
<Keyword>Enum</Keyword>
</Keywords>
<Author>Roger Bovill</Author>
</Header>
<Snippet>
<Declarations>
<Literal Editable="true">
<ID>EnumName</ID>
<ToolTip>Name of the '[Flags]' based enumerated type</ToolTip>
<Default>MyEnumType</Default>
<Function></Function>
</Literal>
</Declarations>
<Code Language="CSharp">
<![CDATA[
#region $EnumName$Extender
public static class $EnumName$Extender
{
// Return lhs flags plus rhs flags
public static $EnumName$ Union(this $EnumName$ lhs, $EnumName$ rhs)
{
return lhs | rhs;
}
// Return flags common to lhs and rhs
public static $EnumName$ Intersection(this $EnumName$ lhs, $EnumName$ rhs)
{
return lhs & rhs;
}
// Return lhs flags minus rhs flags
public static $EnumName$ Subtract(this $EnumName$ lhs, $EnumName$ rhs)
{
$EnumName$ common = lhs & rhs;
int res = (int)lhs - (int)common;
return ($EnumName$)(res);
}
// Return true if lhs contains all the flags within rhs
public static bool Contains(this $EnumName$ lhs, $EnumName$ rhs)
{
$EnumName$ common = lhs & rhs;
return (common == rhs);
}
// Return true if lhs contains one of the flags within rhs
public static bool ContainsAnyOf(this $EnumName$ lhs, $EnumName$ rhs)
{
$EnumName$ common = lhs & rhs;
return ((int)common > 0);
}
// NON-extension methods here
public static $EnumName$ FromString(string source)
{
$EnumName$ res = ($EnumName$)Enum.Parse(typeof($EnumName$), source, true);
return res;
}
}
#endregion $EnumName$Extender
]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
November 13, 2007
DateTime
Here are some links regarding DateTime string formatting and parsing:
M=month digit, y=year digit, d=day digit
h=hour digit (but H=24 hour digit), m=minute digit, s=second digit
Here is an example of this from renaming photos extracted from a digital camera
- DateTime.ToString() Patterns - Copied from MSDN me thinks
- DateTime Parsing
- Standard Date and Time Format Strings - on MSDN
- Coding Best Practices Using DateTime in the .NET Framework
private static DateTime TruncateMilliSeconds(DateTime dt)
{
DateTime trunc = new DateTime(dt.Ticks - (10000*dt.Millisecond));
Debug.Assert(trunc.Millisecond == 0);
return trunc;
}
Parsing a date from a non standard form DateTime.TryParseExact(dateStart, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.AssumeLocal, out m_StartDate);Here is another example that will parse this string "Sun, 30 Jun 2013 14:14:01 +0100"
DateTime when = DateTime.MinValue; string form = @"ddd, dd MMM yyyy HH':'mm':'ss K"; DateTime.TryParseExact(this.rawDateTime, form, System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.AssumeLocal, out when);Converting a date to a non standard string form
string datTimeStr = DateTime.UtcNow.ToString("yyyyMMdd");
whereM=month digit, y=year digit, d=day digit
h=hour digit (but H=24 hour digit), m=minute digit, s=second digit
Here is an example of this from renaming photos extracted from a digital camera
public class PhotoBackupOptions
{
private string m_fileDateFormatStr = "yyyy_MMdd_HHmm";
private string m_filenamePrefix = "Photo_";
public string FileNameDateFormatStr
{
get { return m_fileDateFormatStr; }
}
public string FileNamePrefix
{
get { return m_filenamePrefix; }
}
public string GetPhotoFileName(FileInfo fsi)
{
Debug.Assert((fsi != null) && fsi.Exists);
string res = fsi.Name;
if (FileNameDateFormatStr.Length > 0)
{
DateTime dt = fsi.CreationTime;
res = FileNamePrefix +
dt.ToString(FileNameDateFormatStr) +
fsi.Extension;
}
return res;
}
}
Here is a static method to load a date from a photo's metadata using WPF
// Retrieve the datetime from an image WITHOUT loading the whole thing
public static bool GetDateTakenFromImage(FileInfo fi, out DateTime dateTaken)
{
dateTaken = DateTime.MinValue;
bool found = false;
try
{
using (FileStream fs = new FileStream(fi.FullName,
FileMode.Open, FileAccess.Read, FileShare.Read))
{
BitmapMetadata md = (BitmapMetadata)BitmapFrame.Create(fs).Metadata;
found = DateTime.TryParse(md.DateTaken, out dateTaken);
}
}
catch (Exception)
{
Trace.WriteLine("Could not get DateTaken from the image: \'" + fi.FullName + "\'");
}
return found;
}
C# SQL Update Key Value Type Table
// Updates a table called databaseTableName with columns
// 'Key' and 'Value'. Its untested!
public void UpdateSettingValueEntry(
string databaseTableName, string key, string value)
{
private const string updateCommand =
"UPDATE {0} SET Value = @value WHERE Key = '{1}'"
using (SqlConnection databaseConnection =
new SqlConnection(DatabaseConnectionString))
{
try
{
databaseConnection.Open();
using (SqlCommand command = new SqlCommand())
{
command.Connection = databaseConnection;
command.CommandText = string.format(updateCommand,
databaseTableName, key);
command.Parameters.AddWithValue("@value", value);
Debug.Trace("SQL({0})", command.CommandText);
int rows = command.ExecuteNonQuery();
if (rows == 1)
{
Debug.WriteLine("Updated key \'" + key +
"\' to value of \'" +
value + "\'");
}
else
{
HandleError("Updated key \'" + key +
"\' to value of \'" + value +
"\' returned unexpected row count of \'" +
rows + "\'");
}
if (rows < 1)
{
HandleUpdateError(xxx);
}
}
}
catch (SqlException se)
{
HandleException(se);
}
}
}
C# SQL Update, Insert, Read, Delete
public void UpdateXXXs(XXX[] xxxs)
{
using (SqlConnection databaseConnection =
new SqlConnection(DatabaseConnectionString))
{
try
{
databaseConnection.Open();
SqlTransaction trans =
databaseConnection.BeginTransaction();
// One strategy is to delete the whole table
// and then recreate with the new rows
// it depends on how big the table is. This is
// not practical with a very large table
DeleteXXXTable(databaseConnection, trans);
foreach (XXX xxx in xxxs)
{
InsertXXX(databaseConnection, trans, xxx);
}
trans.Commit();
}
catch (SqlException se)
{
trans.Rollback();
HandleException(se);
}
}
}
private void InsertXXX(SqlConnection databaseConnection,
SqlTransaction trans, XXX xxx)
{
try
{
using (SqlCommand sqlCommand = databaseConnection.CreateCommand())
{
command.Connection = databaseConnection;
command.Transaction = trans;
command.CommandText = "INSERT INTO [XXXTable] " +
"([field1], [field2]) VALUES " +
"(@field1, @field2)";
command.Parameters.AddWithValue("@field1", xxx.field1);
command.Parameters.AddWithValue("@field2", xxx.field2);
Debug.Trace("SQL({0})", command.CommandText);
int rows = command.ExecuteNonQuery();
if (rows < 1)
{
trans.Rollback();
HandleInsertError(xxx);
}
}
}
catch (SqlException se)
{
trans.Rollback();
HandleException(se);
}
}
public XXX[] ReadSomeDatabaseTable()
{
List xxxList = new List();
using (SqlConnection databaseConnection =
new SqlConnection(SomeConnectionString))
{
try
{
databaseConnection.Open();
using (SqlCommand command = new SqlCommand())
{
command.Connection = databaseConnection;
command.CommandText = "SELECT * FROM [XXXTable] ";
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader != null)
{
while (reader.HasRows && reader.Read())
{
string field1 = reader.GetString(0).Trim();
string field2 = reader.GetString(1).Trim();
XXX xxx = new XXX(field1, field2);
xxxList.Add(xxx);
}
}
}
}
}
catch (SqlException se)
{
HandleException(se);
}
}
return xxxList.ToArray();
}
private void DeleteXXXTable(SqlConnection databaseConnection,
SqlTransaction trans)
{
try
{
using (SqlCommand command = databaseConnection.CreateCommand())
{
command.Connection = databaseConnection;
command.Transaction = trans;
command.CommandText = "DELETE FROM [XXXTable];";
command.ExecuteNonQuery();
}
}
catch (SqlException se)
{
trans.Rollback();
HandleException(se);
}
}
November 4, 2007
Using KeyDown Event On A Grid/List Control
This code adds keyboard handling to a grid or list control. The Delete Key performs a Delete, the Insert Key performs an Insert, the Return Key performs a an edit when a single row is selected
private void xxxxxxxxxxxxx_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
// Delete with one or more rows selected
// performs a Remove on those rows
case Keys.Delete:
e.Handled = true;
DeleteSelectedRows();
break;
case Keys.Insert: // Insert performs an Add
e.Handled = true;
AddRow();
break;
// RETURN When a single row is selected
// perform an Edit, editing the currently
// selected row
case Keys.Return:
e.Handled = true;
EditSelectedRow());
break;
default:
break;
}
}
September 23, 2007
Test String Padding Functions
private static void TestPadding()
{
int ix = 0;
string result = string.Empty;
result = ix.ToString("X");
result = result.PadLeft(8, '0');
System.Diagnostics.Debug.Assert(result.Length == 8);
ix = 1;
result = ix.ToString("X");
result = result.PadLeft(8, '0');
System.Diagnostics.Debug.Assert(result.Length == 8);
ix = 9999;
result = ix.ToString("X");
result = result.PadLeft(8, '0');
System.Diagnostics.Debug.Assert(result.Length == 8);
ix = 99999999;
result = ix.ToString("X");
result = result.PadLeft(8, '0');
System.Diagnostics.Debug.Assert(result.Length == 8);
ix = int.MaxValue;
result = ix.ToString("X");
result = result.PadLeft(8, '0');
System.Diagnostics.Debug.Assert(result.Length == 8);
ix = int.MinValue;
result = ix.ToString("X");
result = result.PadLeft(8, '0');
System.Diagnostics.Debug.Assert(result.Length == 8);
}
Using The IComparer and IComparable Interfaces
Sorting and the IComparer and IComparable Interfaces
private class XXXComparer : IComparer{ public XXXComparer() { } #region IComparer Members public int Compare(IXXX x, IXXX y) { return x.SomeProperty.CompareTo(y.SomeProperty); } #endregion } Say you have a list of IXXX, you can sort it with this m_XXX_List.Sort(new XXXComparer()); private class SomeObjectComparer : IComparer { #region IComparer Members public int Compare(object x, object y) { IXXX xi = x as IXXX; IXXX yi = y as IXXX; return xi.SomeProperty.CompareTo(yi.SomeProperty); } #endregion } private class XXX : IComparable { #region IComparable Members public int CompareTo(XXX other) { return this.SomeProperty.CompareTo(other.SomeProperty); } #endregion } Say you have a list of XXX, you can sort it with this m_XXX_List.Sort(); // Simplest Enumerator. Can enumerate the objects without // exposing the underlying list public IEnumerable Processes() { foreach (IProcess process in m_Processes) { yield return process; } }
Enable/Disable Form Close
This disables the system menu file close
private const int SC_CLOSE = 0xF060;
private const int MF_ENABLED = 0x0;
private const int MF_DISABLED = 0x1;
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
private static extern int EnableMenuItem(IntPtr hMenu, int wIDEnableItem, int wEnable);
private void DisableFormClose()
{
EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_DISABLED);
}
private void EnableFormClose()
{
EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_ENABLED);
}
Need to add something that disables the File Close menu
Iterating Over Dictionary Entries
Dictionary<string, XXX> m_MyDictionary = new Dictionary<string, XXX>() foreach (KeyValuePairkvp in m_MyDictionary) { DoSomething(kvp.Key); DoSomethingElse(kvp.Value); }
Using PInvoke
Check out the PInvoke website. Greate Site for finding PInvoke syntax for c# Calls to the WIN 32 API.
A Winforms CheckList
- Check the StartPosition property is CenterParent
- Check the Text property (the Title) is set to something sensible
- IF it is a child window set the 'ShowInTaskbar' property to 'False'
- Check FormBorderStyle property is set to 'FixedDialog' on the Form if it is non-resizable.
- Check MaximiseBox property is set to 'True' on the Form if you want it
- Check MinimiseBox property is set to 'True' on the Form if you want it
- Check AcceptButton property is set on the Form to the 'default' accept/OK button
- Check CancelButton property is set on the Form to the 'default' cancel changes button
- IF you want the OK and cancel buttons to work automatically then set the DialogResult property of the button to Accept or Cancel etc.
- Check the TAB order is set.
this.AcceptButton = this.NAME_OF_ACCEPT_OK_BUTTON;
this.CancelButton = this.NAME_OF_CANCEL_BUTTON;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "FORM TITLE";
Modal/Modeless Dialogs
Modal Dialog
SomeForm sf = new SomeForm();
DialogResult res = sf.ShowDialog(this);
To close a form
... // within the form class itself
DialogResult = DialogResult.OK;
Close();
...
Set the AcceptButton and CancelButton to the correct buttons if required
Modeless Dialog
// Declare the modeless dialog
private MagnifyingGlassForm m_MagFrm = null;
// Creating and showing the modeless dialog
if (m_MagFrm == null)
{
m_MagFrm = new MagnifyingGlassForm();
m_MagFrm.Owner = this; // IMPORTANT Set the owner of the modeless dialog
m_MagFrm.Show(); // Show the modeless dialog
}
...
// To just hide the modeless dialog use Hide() method
m_MagFrm.Hide()
...
// Terminating the Modeless Dialog
if (m_MagFrm != null)
{
m_MagFrm.Close();
m_MagFrm.Dispose();
m_MagFrm = null;
}
May 9, 2007
Using DataTables, DataSets and DataAdaptors
Why use a Dataset?
Using summary
ADO.NET Tutorial
// Use Visual Studio to generate the data set classes. Use 'Typed' datasets //XXXDataSet m_XXXDataSet = new XXXDataSet(); // Create the data table and data adaptors XXXDataSet.XXXDataTable m_XXXDataTable; XXXDataAdapter m_XXXDataAdaptor = new XXXDataAdapter(); // Filling the dataset/datatable m_XXXDataTable = m_XXXDataAdaptor.GetData(); //m_DataAdaptor.Fill(m_XXXDataSet.XXX); //Dont forget to Dispose() //m_XXXDataSet.Dispose(); m_XXXDataTable.Dispose(); m_XXXDataAdaptor.Dispose(); // Finding a record //XXXDataSet.XXXRow lir = m_XXXDataSet.XXX.FindByName(requestor.ToLower()); XXXDataSet.XXXRow lir = m_XXXDataTable.FindByName(requestor.ToLower()); // ADD //m_XXXDataSet.XXX.AddXXXRow(userName, password); m_XXXDataTable.AddXXXRow(userName, password); m_Dirty = true; // DELETE //m_XXXDataSet.XXX.RemoveXXXRow(lir); m_XXXDataTable.RemoveXXXRow(lir); lir.Delete(); // UPDATING the database m_DataAdaptor.Update(m_XXXDataTable); //m_DataAdaptor.Update(m_XXXDataSet);
Double Buffering in C# .Net
Double Buffering in Dot Net 2.0
More Double Buffering in Dot Net 2.0 - Check this out as well
More Double Buffering in Dot Net 2.0 - Check this out as well
bool m_Dirty = true;
Bitmap m_Bitmap;
~XXXCtrl()
{
Dispose(false);
}
public void ChangeSomething(int xmin, int xmax)
{
...
Dirty = true; // Regenerate the bitmap (during the paint cycle)
Invalidate(); // Repaint
}
protected override void OnResize(EventArgs e)
{
_DisposeBitmap();
if ((ClientSize.Width > 0) && (ClientSize.Height > 0))
{
m_Bitmap = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
}
else
{
m_Bitmap = null;
}
Dirty = true;
base.OnResize(e);
Invalidate();
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
Graphics gfx = e.Graphics;
if (Dirty)
{ // Only regenerate the bitmap when something has changed
_RenderToBitmap();
Dirty = false;
}
// Option 1: Redraw entire bitmap
//gfx.DrawRectangle(Pens.Red, e.ClipRectangle);
//_DisplayBitmap(gfx, BitmapRect()); //
// OR
// Option 2: Redraw just the area that has changed
//Debug.WriteLine("Paint: e.ClipRectangle=" +
e.ClipRectangle.ToString());
_DisplayBitmap(gfx, e.ClipRectangle);
}
private void _DisplayBitmap(Graphics gfx, Rectangle clipRectangle)
{
gfx.DrawImage(m_Bitmap, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
}
// Draw the graphics onto a bitmap
private void _RenderToBitmap()
{
using (Graphics gs = Graphics.FromImage(m_Bitmap))
{
_Render(gs, BitmapRect());
}
}
private Rectangle BitmapRect()
{
return new Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height);
}
// Here is the main graphics routine
private void _Render(Graphics ds, Rectangle area)
{
// Draw rectangle around client rectangle and text in centre
Rectangle rect = area;
rect.Height -= 1;
rect.Width -= 1;
using (Brush brush = new SolidBrush(this.BackColor))
{
ds.FillRectangle(brush, rect);
}
ds.DrawRectangle(Pens.Black, rect);
if ((area.Width > 25) && (area.Height > 10))
{
int xpos = 0;
// Draw axis
int x1 = area.Left + 20;
int x2 = area.Right - 20;
int ymid = (area.Height/2);
ds.DrawLine(Pens.Black, new Point(x1, ymid), new Point(x2, ymid));
...
}
}
private bool Dirty
{
get { return m_Dirty; }
set { m_Dirty = value; }
}
private void _DisposeBitmap()
{
if (m_Bitmap != null)
{
m_Bitmap.Dispose();
}
}
and in the designer class
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
_DisposeBitmap();
base.Dispose(disposing);
}
April 13, 2007
Finding a Machine SID in C#
public static class MachineSidHelper
{
private static SecurityIdentifier GetAccountSid(string localAdminAccount)
{
NTAccount name = new NTAccount(localAdminAccount);
SecurityIdentifier sid = (SecurityIdentifier)name.Translate(typeof(SecurityIdentifier));
return sid;
}
// Get the Machine Sid for the PC the code is currently executing on
public static string MachineSid
{
get
{
string machineSid = string.Empty;
string domain;
short accounttype;
try
{
LookupAccountName(Environment.MachineName,
Environment.MachineName, out machineSid,
out domain, out accounttype);
System.Diagnostics.Debug.WriteLine("From LookupAccountName
(\'" + Environment.MachineName + "\', \'" +
Environment.MachineName + "\', ...): " + machineSid);
}
catch (Exception)
{
System.Diagnostics.Trace.WriteLine(
"Can not get the Machine Identifier using \'LookupAccountName\'");
}
if (machineSid.Length < 1)
{
string account = Environment.MachineName + @"\Administrator";
try
{
SecurityIdentifier sid = GetAccountSid(account);
machineSid = sid.AccountDomainSid.ToString();
System.Diagnostics.Debug.WriteLine("From GetAccountSid(\'" + account +
"\'): " + machineSid);
}
catch (Exception)
{
System.Diagnostics.Trace.WriteLine(
"Can not get the Machine Identifier using \'Administrator Sid\'");
}
}
return machineSid;
}
}
internal static bool LookupAccountName(string strServer,
string strAccountName, out string accountSid,
out string strDomainName, out short AccountType)
{
bool bRet = false;
int lSidSize = 256;
int lDomainNameSize = 256;
accountSid = "";
strDomainName = "";
AccountType = 0;
StringBuilder strName;
lSidSize = 0;
IntPtr Sid = IntPtr.Zero;
// First get the required buffer sizes for SID and domain name.
int nRet = Win32API.LookupAccountName(
strServer,
strAccountName,
Sid,
ref lSidSize,
null,
ref lDomainNameSize,
ref AccountType);
bRet = (0 != nRet);
if (!bRet)
{
int nErr = Marshal.GetLastWin32Error();
if (122 == nErr) // Buffer too small
{
// Allocate the buffers with actual sizes that are required
// for SID and domain name.
strName = new StringBuilder(lDomainNameSize);
Sid = Marshal.AllocHGlobal(lSidSize);
nRet = Win32API.LookupAccountName(
strServer,
strAccountName,
Sid,
ref lSidSize,
strName,
ref lDomainNameSize,
ref AccountType);
bRet = (0 != nRet);
if (bRet)
{
byte[] sidArray = new byte[lSidSize];
strDomainName = strName.ToString();
Marshal.Copy(Sid, sidArray, 0, lSidSize);
SecurityIdentifier sid = new SecurityIdentifier(sidArray, 0);
accountSid = sid.ToString();
}
}
else
{
System.Diagnostics.Debug.WriteLine(nErr);
}
}
Marshal.FreeHGlobal(Sid);
return bRet;
}
private class Win32API
{
#region Win32 API Interfaces
[DllImport("Advapi32.dll", SetLastError = true)]
public static extern int LookupAccountName(
string ServerName,
string AccountName,
IntPtr Sid,
ref int SidSize,
StringBuilder DomainName,
ref int DomainNameSize,
ref short SidUse);
#endregion
}
}
Simple C# IEnumerable Samples
This example shows how the iterator can be exposed to allow an object to be iteratied in different ways, In this case a matrix type object can be iterated row by row or column by column. The advantage of the iterator is that it only gets a value when asked.
// Iterate column by column starting with Pin 1,1
public IEnumerable<Thing> ColumnByColum()
{
Thing rcl = new Thing();
for (int col = 0; col < Cols; col++)
{
for (int row = 0; row < Rows; row++)
{
rcl.Row = row + 1;
rcl.Column = col + 1;
yield return rcl;
}
}
}
// Iterate row by row starting with Pin 1,1
public IEnumerable<Thing> RowByRow()
{
Thing rcl = new Thing();
for (int row = 0; row < Rows; row++)
{
for (int col = 0; col < Cols; col++)
{
rcl.Row = row + 1;
rcl.Column = col + 1;
yield return rcl;
}
}
}
foreach (Thing thing in matrixThingey.ColumnByColum)
{
}
There are 2 yield statements:
- "yield return XXX" returns an item.
- "yield break" ends the iterator without returning any item. You can think of yield break as return statement which does not return a value.
Discarding Pending Mouse Or Keyboard Messages in C#
public static class Win32Helper
{
/// Window messages
private enum WindowMessage : uint
{
// Keyboard messages
KeyboardFirst = 0x0100,
KeyboardLast = 0x0108,
// Mouse messages
//MouseMove = 0x0200,
MouseFirst = 0x0201, // Skip mouse move, it happens
//a lot and there is another message for that
MouseLast = 0x020d,
}
public static void DiscardMousebMessages(IntPtr hWnd)
{
Message msg;
while (PeekMessage(out msg, hWnd, (uint)WindowMessage.MouseFirst,
(uint)WindowMessage.MouseLast, (uint)PeekMessageFlags.PM_REMOVE)) ;
}
public static void DiscardKeyboardMessages(IntPtr hWnd)
{
Message msg;
while (PeekMessage(out msg, hWnd, (uint)WindowMessage.KeyboardFirst,
(uint)WindowMessage.KeyboardLast, (uint)PeekMessageFlags.PM_REMOVE)) ;
}
[StructLayout(LayoutKind.Sequential)]
private struct Message
{
public IntPtr hWnd;
public WindowMessage msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("User32.dll", CharSet = CharSet.Auto)]
private static extern bool PeekMessage(
out Message msg, IntPtr hWnd,
uint messageFilterMin, uint messageFilterMax,
uint flags);
}
January 29, 2007
C# SQL
SQL Dos and Donts
SQLDataAdapter without using SQLCommandBuilder. - Useful SQL sample
Data Access Strategies Using ADO.NET and SQL
Lesson 03: The SqlCommand Object - Simplest example possible to start using SqlCOnnection and SqlCommand
Here is some code to save to an SQL database:
SQLDataAdapter without using SQLCommandBuilder. - Useful SQL sample
Data Access Strategies Using ADO.NET and SQL
Lesson 03: The SqlCommand Object - Simplest example possible to start using SqlCOnnection and SqlCommand
Here is some code to save to an SQL database:
using (SqlConnection connection = new SqlConnection(MYDATABASECONFIGURATION.ConnectionString))
{
connection.Open();
SqlTransaction sqlTransaction = connection.BeginTransaction();
try
{
int outcome = SqlStoreSomething(connection, sqlTransaction, thingToStore);
if (outcome == 1)
{
SqlStoreSomethingElse(connection, sqlTransaction, otherThingy);
}
else
{
throw new ApplicationException(msg);
}
}
catch (Exception ex)
{
sqlTransaction.Rollback();
throw ex;
}
sqlTransaction.Commit();
sqlTransaction.Dispose();
connection.Close();
}
private int SqlStoreThingey(
SqlConnection connection,
SqlTransaction sqlTransaction,
SomeThingey thingey)
{
int returnValue = 0;
if ((thingey.Id == Guid.Empty))
{
throw new System.ArgumentOutOfRangeException("Id: " + thingey.Id.ToString());
}
if ((thingey.SomeRef == null))
{
throw new System.ArgumentNullException("SomeRef");
}
using (SqlCommand sqlCmd = new SqlCommand())
{
sqlCmd.Connection = connection;
sqlCmd.Transaction = sqlTransaction;
sqlCmd.CommandText =
@"INSERT INTO [dbo].[MasterThingeyTable] ([Id], [SomeRef], [Date] " +
@") VALUES (@Id, @SomeRef, @Date, )";
sqlCmd.CommandType = System.Data.CommandType.Text;
sqlCmd.Parameters.Add(new SqlParameter("@Id", System.Data.SqlDbType.UniqueIdentifier, 0,
System.Data.ParameterDirection.Input, 0, 0, "Id", System.Data.DataRowVersion.Current, false, null, "", "", ""));
sqlCmd.Parameters.Add(new SqlParameter("@SomeRef", System.Data.SqlDbType.NVarChar, 0,
System.Data.ParameterDirection.Input, 0, 0, "SomeRef", System.Data.DataRowVersion.Current, false, null, "", "", ""));
sqlCmd.Parameters.Add(new SqlParameter("@Date", System.Data.SqlDbType.DateTime, 0,
System.Data.ParameterDirection.Input, 0, 0, "Date", System.Data.DataRowVersion.Current, false, null, "", "", ""));
sqlCmd.Parameters[0].Value = ((System.Guid)(thingey.Id));
sqlCmd.Parameters[1].Value = ((string)(thingey.SomeRef));
sqlCmd.Parameters[2].Value = ((System.DateTime)(thingey.Date));
returnValue = sqlCmd.ExecuteNonQuery();
}
return returnValue;
}
January 26, 2007
Simple Wizard Form
The SimpleWizardForm.designer.cs contenst are not here. Put 3 buttons on the Wizard form, 'butCancel', 'butPrevious' and 'butNext'. Use a 2 pixel high label control to get a bevel.
public partial class SimpleWizardForm : Form
{
protected readonly string NEXT_BUT = @"&Next >";
protected readonly string FINISH_BUT = @"Fi&nish";
private Control[] panels;
private readonly Size MaxPanelSize = new Size(590, 462);
private readonly Point PanelOffset = new Point(0, 56);
private int m_pos = 0;
public SimpleWizardForm(Image img)
{
InitializeComponent();
InitWizardImage(img);
}
private void InitWizardImage(Image img)
{
}
// Takes an array or list or whatever of that are to
// be shown in the Wizard form. They are shown in the
// order that they are defined in the list.
protected void Initialise(IList argPanels)
{
panels = new Control[argPanels.Count];
int ix = 0;
foreach (Control ctrl in argPanels)
{
panels[ix++] = ctrl;// Add the control to the wizard array
System.Diagnostics.Debug.Assert(
(ctrl.Size.Width < MaxPanelSize.Width) &&
(ctrl.Size.Height < MaxPanelSize.Height),
"Passed a control to the WizardForm which is larger in size (= " +
ctrl.Size.ToString() + ") than the area available (=" +
MaxPanelSize.ToString() + ") for showing panels!");
this.Controls.Add(ctrl);
ctrl.Location = new Point(
PanelOffset.X + (MaxPanelSize.Width-ctrl.Width) / 2,
PanelOffset.Y + (MaxPanelSize.Height-ctrl.Height) / 2);
ctrl.Visible = false; // All panels are invisible
}
m_pos = 0;
// Make first panel visible
panels[m_pos].Visible = true;
UpdatePrevNextButts();
}
private void butNext_Click(object sender, EventArgs e)
{
NextPanel();
UpdatePrevNextButts();
}
private void butPrev_Click(object sender, EventArgs e)
{
PreviousPanel();
UpdatePrevNextButts();
}
private void NextPanel()
{
// If this is the last panel
if (m_pos == (panels.Length - 1))
{
// Close the dialog with a successful outcome
this.DialogResult = DialogResult.OK;
Close();
}
else
{
// Show the next panel
panels[m_pos].Visible = false;
m_pos = (m_pos + 1) % panels.Length;
panels[m_pos].Visible = true;
}
}
private void PreviousPanel()
{
panels[m_pos].Visible = false;
m_pos = (m_pos + 1 + panels.Length) % panels.Length;
panels[m_pos].Visible = true;
}
private void UpdatePrevNextButts()
{
if (IsLastPanel())
{
butNext.Text = FINISH_BUT;
}
else
{
butNext.Text = NEXT_BUT;
}
butPrev.Enabled = (!IsFirstPanel());
}
private bool IsLastPanel()
{
return m_pos == (panels.Length - 1);
}
private bool IsFirstPanel()
{
return (m_pos == 0);
}
private void butCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
Close();
}
}
And the corresponding WizardForm.Designer.cs
partial class WizardForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed;
otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.bevelControl1 = new System.Windows.Forms.Label();
this.butPrev = new System.Windows.Forms.Button();
this.butNext = new System.Windows.Forms.Button();
this.butCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// bevelControl1
//
this.bevelControl1.Anchor =
((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.bevelControl1.Location = new System.Drawing.Point(-26, 524);
this.bevelControl1.Name = "bevelControl1";
this.bevelControl1.Size = new System.Drawing.Size(645, 2);
this.bevelControl1.TabIndex = 59;
//
// butPrev
//
this.butPrev.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom |
System.Windows.Forms.AnchorStyles.Left)));
this.butPrev.Location = new System.Drawing.Point(299, 534);
this.butPrev.Name = "butPrev";
this.butPrev.Size = new System.Drawing.Size(75, 23);
this.butPrev.TabIndex = 57;
this.butPrev.Text = "< &Previous";
this.butPrev.UseVisualStyleBackColor = true;
this.butPrev.Click += new System.EventHandler(this.butPrev_Click);
//
// butNext
//
this.butNext.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom |
System.Windows.Forms.AnchorStyles.Left)));
this.butNext.Location = new System.Drawing.Point(390, 534);
this.butNext.Name = "butNext";
this.butNext.Size = new System.Drawing.Size(75, 23);
this.butNext.TabIndex = 56;
this.butNext.Text = "&Next >";
this.butNext.UseVisualStyleBackColor = true;
this.butNext.Click += new System.EventHandler(this.butNext_Click);
//
// butCancel
//
this.butCancel.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom |
System.Windows.Forms.AnchorStyles.Left)));
this.butCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.butCancel.Location = new System.Drawing.Point(127, 534);
this.butCancel.Name = "butCancel";
this.butCancel.Size = new System.Drawing.Size(75, 23);
this.butCancel.TabIndex = 58;
this.butCancel.Text = "&Cancel";
this.butCancel.UseVisualStyleBackColor = true;
this.butCancel.Click += new System.EventHandler(this.butCancel_Click);
//
// WizardForm
//
this.AcceptButton = this.butNext;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.butCancel;
this.ClientSize = new System.Drawing.Size(593, 565);
this.Controls.Add(this.panelBrandHeader);
this.Controls.Add(this.bevelControl1);
this.Controls.Add(this.butPrev);
this.Controls.Add(this.butNext);
this.Controls.Add(this.butCancel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "XXXWizardForm";
this.StartPosition =
System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "XXX Wizard Form";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label bevelControl1;
private System.Windows.Forms.Button butPrev;
private System.Windows.Forms.Button butNext;
private System.Windows.Forms.Button butCancel;
}
January 8, 2007
Simple Usage of OpenFileDialog and SaveFileDialog
Insert the following dialog methods into a dialog service class.
OpenFileDialog
public string SelectFileToOpenDialog()
{
string fileName = string.Empty;
using (OpenFileDialog of = new OpenFileDialog())
{
of.Title = "Open the Hot Fix details file";
of.Filter = "XXX file (*.xxx)|*.xxx|All files (*.*)|*.*";
if (of.ShowDialog() == DialogResult.OK)
{
fileName = of.FileName;
}
}
return fileName;
}
SaveFileDialog
private string GetSaveFileName()
{
string fileName = string.Empty;
// Create new SaveFileDialog object
using (SaveFileDialog saveFileDlg = new SaveFileDialog())
{
saveFileDlg.SupportMultiDottedExtensions = true;
// Default file extension
saveFileDlg.DefaultExt = ".zip";
// Set initial filename (file only NOT directory/path)
saveFileDlg.FileName = "Changes." + DateTime.UtcNow.ToString("yyyyMMdd");
// Available file extensions
saveFileDlg.Filter = "Batch file (*.zip)|*.zip|All files (*.*)|*.*";
// Adds a extension if the user does not
saveFileDlg.AddExtension = true;
// Restores the selected directory, next time
//saveFileDlg.RestoreDirectory = true;
// Dialog title
saveFileDlg.Title = "Where do you want to save the 'zip' file?";
// Startup directory
//saveFileDlg.InitialDirectory = @"C:/";
// Show the dialog and process the result
if (saveFileDlg.ShowDialog() == DialogResult.OK)
{
if (File.Exists(saveFileDlg.FileName))
{
File.Delete(saveFileDlg.FileName);
}
fileName = saveFileDlg.FileName;
}
}
return fileName;
}
SaveFileDialog Snippet
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Keywords>
<Keyword>SaveFileDialog</Keyword>
</Keywords>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
<Title>SnippetFile1</Title>
<Author>Roger</Author>
<Description>SaveFileDialog</Description>
<HelpUrl>
</HelpUrl>
<Shortcut>SaveFileDialog</Shortcut>
</Header>
<Snippet>
<Declarations>
<Literal Editable="true">
<ID>bat</ID>
<ToolTip>default file extension</ToolTip>
<Default>txt</Default>
<Function>
</Function>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[
private void SaveFileDialog(string text)
{
// Create new SaveFileDialog object
using (SaveFileDialog saveFileDlg = new SaveFileDialog())
{
saveFileDlg.SupportMultiDottedExtensions = true;
// Default file extension
saveFileDlg.DefaultExt = "$bat$";
// Available file extensions
saveFileDlg.Filter = "Batch file (*.$bat$)|*.$bat$|All files (*.*)|*.*";
// Adds a extension if the user does not
saveFileDlg.AddExtension = true;
// Restores the selected directory, next time
//saveFileDlg.RestoreDirectory = true;
// Dialog title
saveFileDlg.Title = "Where do you want to save the 'batch' file?";
// Startup directory
//saveFileDlg.InitialDirectory = @"C:/";
// Show the dialog and process the result
if (saveFileDlg.ShowDialog() == DialogResult.OK)
{
//SaveFileImplement(sf.FileName);
if (!File.Exists(saveFileDlg.FileName))
{
File.WriteAllText(saveFileDlg.FileName, text);
}
}
}
}
]]></Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
Labels:
Code Snippet,
OpenFileDialog,
SaveFileDialog
Making a form a fixed sized dialog box without a Minimise or Maximise buttons
this.FormBorderStyle = FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false;
January 2, 2007
Creating A Temp File In The Temporary directory
Use a specific file name in the temporary directory:
"C:\Users\RB\AppData\Local\Temp\tmp517F.bat"
private readonly string testPath =
Path.Combine(Path.GetTempPath(), "TestSerializer.xml");
Create a temporary file name in the temporary directory but with a specified extension:public static class PathClassExtender
{
public static string GetTempFileName(string newExtension)
{
string res = Path.ChangeExtension(Path.GetTempFileName(), newExtension);
return res;
}
}
Sample usage:string filename = PathClassExtender.GetTempFileName(".bat");
filename will get set to something like"C:\Users\RB\AppData\Local\Temp\tmp517F.bat"
Controlling TextBox Character Input
Good set opf samples
/// <summary>
/// Ensure only alpha numeric characters and
/// backspace are acceptable characters for the Thingey
/// </summary>
/// <param name="sender"></param>
/// <param name="kpea"></param>
private void OnSomeTextBox_KeyPressEvent(object sender,
KeyPressEventArgs kpea)
{
const char BACKSPACE = '\b';
const char FULLSTOP = '.';
if (textBox.Text.Length > 0) // AFter first character
{
if ( !Char.IsLetterOrDigit(kpea.KeyChar) &&
(kpea.KeyChar != BACKSPACE) &&
(kpea.KeyChar != FULLSTOP))
{ // input is not passed on to the control(TextBox)
kpea.Handled = true;
}
} // First character must be an alphabetic character
else if (!Char.IsLetter(kpea.KeyChar))
{
// input is not passed on to the control(TextBox)
kpea.Handled = true;
}
}
// Another example
switch(kpea.KeyChar)
{
case 'a':
case 'b':
case 'c':
case '#':
case '*':
case '1':
e.Handled=true; //event is handled.
this.errorProvider.SetError(this.textboxChars,
"not allowed chars: 'a','b','c','#','*','1'");
this.statusBar.Text="not allowed char..."+e.KeyChar;
break;
default:
//clear error
this.errorProvider.SetError(this.textboxChars, "");
break;
} //switch
private static class FilterCharacters
{
public static void FilterSample(TextBox tb,
KeyPressEventArgs kpea)
{
const char BACKSPACE = '\b';
const char FULLSTOP = '.';
const char HYPHEN = '-';
const char UNDERSCORE = '_';
if (tb.Text.Length > 0)
{
if (!Char.IsLetterOrDigit(kpea.KeyChar) &&
(kpea.KeyChar != BACKSPACE) &&
(kpea.KeyChar != FULLSTOP) &&
(kpea.KeyChar != HYPHEN) &&
(kpea.KeyChar != UNDERSCORE) )
{ // input is not passed on to the control(TextBox)
kpea.Handled = true;
}
}// First character must be an alphabetic character
else if (!Char.IsLetter(kpea.KeyChar))
{// input is not passed on to the control(TextBox)
kpea.Handled = true;
}
}
public static void NumericOnlyFilter(TextBox tb,
KeyPressEventArgs kpea)
{
const char BACKSPACE = '\b';
//const char FULLSTOP = '.';
if (!Char.IsDigit(kpea.KeyChar) &&
// If you want decimal numbers
//(kpea.KeyChar != FULLSTOP) &&
(kpea.KeyChar != BACKSPACE) )
{
kpea.Handled = true;
}
}
}
Creating A Hash Of A String
// A quick and simple implementation
public string HashString(string target)
{
if ((target == null) || (target.Length == 0))
return string.Empty;
byte[] targetAsBytes = Encoding.UTF8.GetBytes(target);
SHA1 sha1 = SHA1.Create();
byte[] hash = sha1.ComputeHash(targetAsBytes);
return Convert.ToBase64String(hash);
}
Subscribe to:
Comments (Atom)