// 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");where
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
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() { ListxxxList = 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(IListAnd the corresponding WizardForm.Designer.csargPanels) { 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(); } }
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.
OpenFileDialogpublic 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:
Posts (Atom)