tag:blogger.com,1999:blog-99240162008-07-03T10:58:41.453+01:00You're a good looking blog, what's your owner's name?Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comBlogger98125tag:blogger.com,1999:blog-9924016.post-42659295781136974072007-10-17T10:27:00.000+01:002007-10-17T10:29:57.118+01:00Visual Studio 2005 ASP.NET F5 Debugging performanceI was experiencing a delay of about a minute between pressing F5 to start debugging my ASP.NET application (VS2005 SP1, Vista) and anything appearing in the browser.<br /><br />After researching this and installing various hotfixes, nothing improved. Removing the google toolbar however seemed to make debugging return to its normal speed.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-80575511923740355092007-09-05T11:12:00.000+01:002007-09-05T11:16:35.044+01:00ASP/ASPX pages giving 404 errorsIn case I need to do this in future... I have been trying to copy a web site to a new web server (Windows Server 2003) and getting very confused about why .ASP and .ASPX pages were giving 404 errors, but HTML pages were displaying correctly. The reason was "ASP.NET" and "Active Server Pages" in the Web Service Extensions directory were both set to "Prohibited".Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-9455233550096668422007-08-29T13:21:00.000+01:002007-08-29T13:27:39.288+01:00The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.I was getting an error message "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel." when trying to connect to an HTTPS site using an HttpWebRequest.<br /><br />As the site I was connecting to was a test site from a 3rd party known to me, but not set up correctly at their end, to bypass this check I added the following line before calling GetRequestStream on my HttpWebRequest.<br /><br /><pre><br />ServicePointManager.ServerCertificateValidationCallback <br />+= new <br />System.Net.Security.RemoteCertificateValidationCallback<br />(CustomValidation);<br /></pre><br /><br />and added the CustomValidation function as follows:<br /><br /><pre><br />private static bool CustomValidation(object sender, <br />X509Certificate cert, X509Chain chain, <br />System.Net.Security.SslPolicyErrors error)<br />{<br /> return true;<br />}<br /></pre>Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-89793796216888054122007-08-06T08:40:00.000+01:002007-08-06T08:41:47.848+01:00A set of principles for taking a new assignment<a href=http://secretsofconsulting.blogspot.com target=_blank>Gerald M. Weinberg</a> offers a <a target=_blank href=http://secretsofconsulting.blogspot.com/2007/07/working-conditions-that-prevent.html> set of principles</a> for taking on a new assignment.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-16282049684989519422007-06-12T17:05:00.000+01:002007-06-12T17:10:56.886+01:00InternalsVisibleToAttribute, Unit Testing and Strong NamesI previously posted about using the InternalsVisibleTo attibute for testing with NUnit.<br /><br />I've had some problems building this with a stronly named assembly. I found the <a href="http://kentb.blogspot.com/2005/11/internalsvisibletoattribute.html">following post</a> on Kent Boogaart's blog that describes how you should change the code in your assemblyinfo.cs file as follows:<br /><br />[assembly: InternalsVisibleTo("Company")]<br /><br />to<br /><br />[assembly: InternalsVisibleTo("Company, PublicKey=xxxxxxxxxxxxxxxx")]Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-17891944812593131182007-06-12T16:35:00.000+01:002007-06-12T17:04:50.053+01:00Adding a strong name to a third party dllI've been trying to build an assembly with a strong name and had some problems as it referenced a 3rd party assembly which had been built without a strong name.<br /><br />To add a strong name I disassembled and reassembled the 3rd party assmbly as follows:<br /><br />ildasm /out:thirdparty.dll.il thirdparty.dll<br /><br />ilasm /dll /resource=thirdparty.dll.res thirdparty.dll.il /out=thirdparty.dll /key=mykey.snkRichard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-5901465127944301912007-06-05T14:07:00.001+01:002007-06-05T14:10:08.165+01:00World Environment DayTo celebrate World Environment Day, we have all been given a flowerpot, some peat and some forget-me-not seeds. You can follow whether the seeds grow into a beautiful plant or not <a href="http://www.richardjonas.com/vergissmeinnicht">here</a>.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-74209837067133700742007-06-05T14:01:00.000+01:002007-06-05T14:05:33.958+01:00Refreshing Progress BarsI've been having some problems getting a progress bar to refresh, trying various calls to Refresh() and Invalidate() without much success. The solution to this is to create the dialog containing the progress bar in another thread, as described <a href="http://www.codeguru.com/forum/showthread.php?t=356916">here</a>.<br /><br />Although the dialog is modeless, it should be displayed using ShowDialog(), not Show().Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-84130140889911013382007-05-16T10:29:00.000+01:002007-05-16T10:47:36.971+01:00Standard for improving Standards<a href="http://www.think-box.co.uk/blog/">Simon Baker</a> suggests that <a href="http://www.think-box.co.uk/blog/2007/05/does-standardisation-suppress.html">standardisation does not have to supress innovation</a>.<br /><br />It's important to communicate the best ways of doing things, but standards are often enforced in a way that people are expected to accept without question. However, there are often many ways of doing something, and the best way will change over time with changes in technology and changes in people.<br /><br />Perhaps standards should be seen as something that should be followed, but when its thought they cause a problem, judgement should be used as to the correct procedure should be followed. However, if people use judgement to deviate from the standard, any differences should be noted and their effect should be considered afterwards.<br /><br />The differences can then be assessed to see if deviating from the standard was the right thing with hindsight and if so, the standard should be improved. if it was the wrong thing to do, we might need to explain the rationale behind the standard better.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-25404372386607740712007-04-16T11:21:00.000+01:002007-04-16T11:42:34.817+01:00Visual Studio 2005 - Disappearing controls on Windows FormMy computer crashed the other day and when I returned to edit my application, to my horror I noticed that the controls on a very complicated windows form that I was working on had vanished. When I tried to edit it, all I got was an empty dialog box, but all the source code for my form was still there. <br /><br />I found several references to disappearing controls in VS2003, but they all said the problem had been fixed in VS2005.<br /><br />The cause of this turned out to be that some lines had removed themselves from the designer.cs file :-<br /><br /><blockquote><br />///<br />/// formMyForm<br />///<br />this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);<br />this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;<br />this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;<br />this.ClientSize = new System.Drawing.Size(869, 717);<br />this.Controls.Add(this.splitContainer1);<br />this.Controls.Add(this.buttonOK);<br />this.Controls.Add(this.buttonCancel);<br />this.Controls.Add(this.buttonAccept);<br />this.Name = "formMyForm";<br />this.Text = "My form title";<br /></blockquote><br /><br><br /><br />Copying these lines from the version in source control seemed to restore all the controls in the dialog.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-86836333519815744532007-03-01T16:23:00.000Z2007-03-01T16:27:31.941ZComplete years between 2 datesA problem we have had calculating ages was due to it using the SQL Server "DateDiff" function. This counts the number of times a day crosses a boundary, e.g.<br /><br />DateDiff(year,'12/31/2006','1/1/2007') is 1, as it crosses the 2006-2007 boundary.<br />DateDiff(year,'1/1/2006','12/31/2006') is 0 as it doesn't cross a year boundary.<br /><br />I have written a function "yeardiff", which calculates the number of complete years between 2 dates, so<br /><br />YearDiff('12/31/2006','1/1/2007') is 0<br />YearDiff('1/1/2006','12/31/2006') is 0<br />YearDiff('12/31/2006','1/1/2008') is 1<br /><br />This function works by calculating the number of days the start date is into the year, subtracting this from both start and end dates (so the start date is 1 January), and calling DateDiff on the resulting date. <br /><br />Here's the source code for this function:<br /><br /><blockquote><br />CREATE FUNCTION yeardiff<br />(@start as datetime, @end as datetime)<br />returns int<br />AS<br />BEGIN<br /> declare @years as int<br /><br /> declare @daysintoyear as int<br /> declare @firstdayofyear as datetime<br /> declare @newstart as datetime<br /> declare @newend as datetime<br /><br /> set @firstdayofyear = convert(datetime,<br />'1/1/'+convert(varchar,year(@start)))<br /> set @daysintoyear =datediff(day, @start, @firstdayofyear)<br /><br /> set @newstart = dateadd(dd, @daysintoyear,@start)<br /> set @newend = dateadd(dd, @daysintoyear,@end)<br /><br /> return datediff(year,@newstart,@newend) <br /><br />END<br /></blockquote>Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-45727069926141294142007-02-06T17:04:00.000Z2007-02-06T17:19:12.169ZNant and licensed 3rd party controlsI've been having some problems building a project containing licensed grid and graph components from ComponentOne using NAnt. The project built correctly in Visual Studio, but when built with NAnt I got a box saying the component was not licensed.<br /><br />I've found some others have had similar problems, but no solutions have been posted. I go it working after a lot of trial and error as follows:<br /><br />1) Use an &lt;exec&gt; task to run the license compiler (lc.exe).<br />2) Ensure the /target: command does not contain a path.<br />3) Ensure your &lt;csc&gt; task does not contain a path in its output section.<br />4) Ensure the licenses file is included in the resources section. This did not work when it was included as an argument with an &lt;arg value="/resource" element.<br />5) Copy the file to the correct destination directory at the end.<br /><br />Here's the relevant part of my build file.<br /><br /><font face=arial size=1><br /> &lt;target name="project" description="build project"<br /> depends="..." &gt;<br /><br /><br /> &lt;exec program="C:\Program Files\Microsoft <br />Visual Studio 8\SDK\v2.0\bin\LC.exe"<br /> commandline="/target:project.exe <br />/complist:c:/nantcheckout/project/Properties\<br />licenses.licx <br />/outdir:c:/nantbuild /i:c:\nantbuild\C1.Data.2.dll <br />/i:c:\nantbuild\C1.Win.C1Chart.2.dll <br />/i:c:\nantbuild\C1.Win.C1Chart3D.2.dll <br />/i:c:\nantbuild\CAInterfaces.dll <br />/i:c:\nantbuild\CDERules.dll <br />/i:c:\nantbuild\clTreeViewHashT.dll <br />/i:C:\WINDOWS\Microsoft.NET\Framework\<br />v2.0.50727\System.configuration.dll <br />/i:C:\WINDOWS\Microsoft.NET\Framework\<br />v2.0.50727\System.Data.dll <br />/i:C:\WINDOWS\Microsoft.NET\Framework\<br />v2.0.50727\System.Deployment.dll <br /><br />...<br /><br />/&gt;<br /><br /> &lt;csc target="winexe" <br />output="PCOBrowserGE.exe" debug="false" <br />define="TRACE" &gt;<br /> &lt;sources&gt;<br /> &lt;include name="c:/nantcheckout/<br />project/*.cs" /&gt;<br /> &lt;include name="c:/nantcheckout/<br />project/Properties/*.cs" /&gt;<br /> &lt;/sources&gt;<br /> &lt;resources&gt;<br /> &lt;include name="c:/nantcheckout/<br />project/Properties/*.resx" /&gt;<br /> &lt;include name="c:/nantcheckout/<br />project/*.resx" /&gt;<br /> &lt;include name="c:/nantbuild/<br />project.exe.licenses" /&gt;<br /> &lt;/resources&gt;<br /> &lt;arg value="/reference:C:\nantbuild\<br />c1.win.c1chart.2.dll" /&gt;<br /> &lt;arg value="/reference:C:\nantbuild\<br />c1.win.c1chart3d.2.dll" /&gt;<br /> &lt;arg value="/reference:C:\nantbuild\<br />c1.data.2.dll" /&gt;<br /> &lt;/csc&gt;<br /><br /> &lt;copy file="pcobrowserge.exe" tofile="<br />c:/nantbuild/project.exe" /&gt;<br /> &lt;/target&gt;<br /></font>Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-72132466281046493532007-02-06T10:11:00.000Z2007-02-06T10:15:01.639Z10 Characteristics of a great programmer<a href="http://eureka3d.com/blog/about/">Steve Riley</a> has complied a great list of the <a href="http://eureka3d.com/blog/2007/the-top-10-attributes-of-a-great-programmer/">10 characteristics of a great programmer</a>.<br /><br />I'd agree with everything on the list - the one thing that is missing is that great programmers know why they are doing what they are doing - there's no point producing an excellent solution to the wrong problem.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1169720622890436172007-01-25T10:14:00.000Z2007-01-25T10:23:43.213ZCakes<a href="http://www.redmonk.com/cote/2007/01/23/requirements-gathering-and-cakes/">Cote</a> writes about requirements gathering and cakes.<br /><br />If your powerful boss asks you for a cake, you can't easily find out the details of what he wants. You have to find out via secondary sources (e.g. the boss's calendar, asking the baker what sort of cakes the boss has ordered before). The calendar may not be up to date, and the baker may not remember accurately.<br /><br />This takes longer and is more likely to go wrong. If there are more steps than necessary in finding out requirements, the solution is to understand what the difficulty is with asking him directly and work on reducing these difficulties.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1169655063535856962007-01-24T15:44:00.000Z2007-01-24T16:14:35.606ZPersonal Search FilterIf you want to find out information about something, you will typically enter terms into a search engine.<br /><br />The search engine will determine which results are most relevant (by using a complex algorithm based on how important it thinks the pages are). Everybody using this search engine will see the same results. <br /><br />The things you want to see might not be the same as the things others want to see. However, you are more likely to want to see things that people "compatible with you" liked. If A likes B and B likes C, and B also likes D, then chances are that A will like D.<br /><br />You could filter the results of your search (from the search engine) through a personal search filter. This would reorder your searches depending on <br /><br />1) Things you have liked before<br />2) Things that people compatible with you have liked before.<br /><br />When you visit a web page, you record whether you found it valuable. This updates your personal search filter and how compatible you are with other people. If you liked page A and B didn't like page A, you will not value the opinion that B liked page C. However if B liked A, you would be compatible with B and their opinion would affect your search filter.<br /><br />This can be seen below:<br /><br /><image src=http://www.richardjonas.com/images/psf.png>Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1168600475153161862007-01-12T10:21:00.000Z2007-01-12T11:14:35.216ZAnti-tests<a href="http://fishbowl.pastiche.org/">Charles Miller</a> describes the concept of an "<a href="http://fishbowl.pastiche.org/2007/01/09/revenge_of_the_antitest">Anti-Test</a>", which is a test that verifies a bug exists.<br /><br />This can be written when the problem is discovered, even if it's not going to be fixed immediately.<br /><br />It means that if the problem is inadvertently fixed as a result of something else, we know this has happened, have a look at why this is the case and update our records accordingly. The test can then be changed to a normal test to make sure it doesn't go wrong again.<br /><br />When you're ready to fix an anti-test, you can change it to a normal test - it should now fail (and this change should be easy to make), fix the bug and make sure the test passes.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1168596968911489152007-01-12T10:09:00.000Z2007-01-12T10:16:08.926ZNAnt versionI've been trying to add version numbers to a <a href="http://nant.sourceforge.net/">NAnt</a> build script using the <a href="http://nantcontrib.sourceforge.net/release/0.85-rc3/help/tasks/version.html">&lt;version&gt; task</a>, and come across a problem with the script in <a href="http://www.amazon.co.uk/Expert-Delivery-Using-Cruisecontrol-Net-Experts/dp/1590594851/sr=8-2/qid=1168596717/ref=sr_1_2/202-5030835-5298214?ie=UTF8&s=books">Marc Holmes' "Expert .NET delivery" book</a>. <br /><br />The <version> task increments a property called "buildnumber.version", not "sys.version". Adding the following line to the script (as described <a href="http://frazzleddad.blogspot.com/2005/07/versioning-using-nant.html">here</a>) seems to fix it.<br /><br />&lt;property name="sys.version" value="${buildnumber.version}" /&gt;Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1165167433315514302006-12-03T16:22:00.000Z2006-12-03T17:59:49.823ZUsing attributes to specify the contents of a menu<p>Most people think it is a good idea to separate business and presentation logic in your application, so you can update one without changing the other. When you create an application with a menu bar, the menu items will often call functions in your business logic, and&nbsp;if you add a new business logic function you will need to add a handler in your presentation layer and the business logic function in your business logic layer.</p><br /><p>This article describes how you can add attributes in your business logic layer and have these dynamically bound to a menu when your application runs. The attributes will look like the following:</p><br /><blockquote><pre> public class MenuHandler<br /> {<br /> [MenuOption ("Menu Option 1")]<br /> public void MenuHandler(object sender, <br />EventArgs e)<br /> {<br /> //Business Logic<br /> }<br /> }</pre></blockquote><br /><br /><b>Creating your Attribute</b><br><br /><P>The first thing you need to do is to set up your attribute. Create a class derived from System.Attribute as follows.</P><br /><blockquote><pre> [AttributeUsage(AttributeTargets.Method)]<br /> public class MenuOptionAttribute : <br />System.Attribute<br /> {<br /> private string MenuText;<br /><br /> public MenuOptionAttribute(String <br />menutext)<br /> {<br /> MenuText = menutext;<br /> }<br /><br /> public string GetMenuText<br /> {<br /> get<br /> {<br /> return MenuText;<br /> }<br /> }<br /> }<br /></pre></blockquote><br /><br>The first line of this specifies your attribute can be applied to methods (and not to classes). The constructor takes one argument, which is a string representing the menu text.<br><br><br /><b>Applying your attribute to your business logic</b><br><br /><P>Next, you write your business logic layer to use the MenuOption attribute. All you need to do is to put this before any functions you want on your menu, with the text to go on your menu:</P><br /><blockquote><pre> public class BusinessLogic<br /> {<br /> [MenuOption ("Menu Option 1")]<br /> public void Option1(object sender, <br />EventArgs e)<br /> {<br /> // Option 1 code<br /> }<br /><br /> [MenuOption("Option 2")]<br /> public void Option2(object sender, <br />EventArgs e)<br /> {<br /> // Option 2 code<br /> }<br /></pre></blockquote><br /><P>You can add as many of these functions as you like.</P><br /><b>Setting up your menu</b><br /><P>Finally, you need to create your presentation layer. You can drag a MenuStrip to a form and add a title for your drop down menu. If you call the title "Main", when you add the title, it will create a ToolStripMenuItem, called "mainToolStripMenuItem" by default.</P><br /><P>You need to use reflection to iterate over all the methods in the MenuHandler class, and see which of those methods have the MenuOptionAttribute attribute set.</P><br /><P>If it is set, you need to call the GetMenuText() function on the attribute to find out the text to display on the menu bar and add the menu item.</P><br /><P>Next, you need to create a delegate to your method.</P><br /><P>Finally, you add the event handler to your newly created menu item. It's easier to understand this if you read the code example.</P><br /><blockquote><pre> public partial class Form1 : Form<br /> {<br /> public Form1()<br /> {<br /> InitializeComponent();<br /> BusinessLogic bl = new BusinessLogic();<br /><br /> mainToolStripMenuItem.DropDownItems.<br />Clear();<br /> foreach (MethodInfo method in <br />(typeof (BusinessLogic)).GetMethods())<br /> {<br /> foreach (object attribute in <br />method.GetCustomAttributes(true))<br /> {<br /> if (attribute is <br />MenuOptionAttribute)<br /> {<br /> ToolStripItem newitem = <br />mainToolStripMenuItem.DropDownItems.Add((<br />attribute as MenuOptionAttribute).GetMenuText);<br /> EventInfo ci = typeof<br />(ToolStripItem).GetEvent("Click");<br /> Type tdelegate = ci.<br />EventHandlerType;<br /> Delegate del = Delegate.<br />CreateDelegate(tdelegate,bl,method);<br /> ci.AddEventHandler(<br />newitem, del);<br /> }<br /> }<br /> }<br /> }<br /> }<br /></pre></blockquote><br />You could add some code to your attribute to specify its position, and use this to order your menu items. You might want to specify more than one string, one for the heading and one for the item itself, so you can put menu items in under different headings.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1161433307617627812006-10-21T13:10:00.000+01:002006-10-21T13:21:48.050+01:00InternalsVisibleToAttribute and Unit TestingWhen creating unit tests to be run with NUnit, I like to keep my tests in a separate assembly, which is not delivered when my project is deployed. <br /><br />This can make it difficult to create unit tests for classes that should not be visible outside of that assembly. One of my classes uses one of 3 strategy classes that encapsulate a feature of the business logic. I would normally declare these with the intern access modifier, but to test each strategy works I've needed to make them publically available.<br /><br />If, however, I add the [assembly: InternalsVisibleTo("UnitTests")] line to my AssemblyInfo.cs file, any objects declared with the intern access modifier can be seen by the UnitTests assembly.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1160516652804734412006-10-10T22:33:00.000+01:002006-10-10T22:44:12.820+01:00Processes and PracticesJared Richardson <a href="http://www.jaredrichardson.net/blog/2006/10/10#simple-process">describes a process</a> he wants his team to follow. Many others have attempted the same and have reached similar conclusions, and I can't disagree with any of Jared's thoughts. <br /><br />However, I think he misses out the most important part of the process which should be to regularly think about your process and what you have done and how you could have done it better. All processes and practices should be adaptable. Different people have different strengths and new technologies mean we have to develop things in different ways.<br /><br />A lot has been written about <a href="http://www.think-box.co.uk/blog/2005/11/repaying-technical-debt.html">technical debt</a>, where if not enough time is invested in developing high quality software, it becomes harder to maintain and costs of new developments increase over time. We should also think about process debt, where if not enough time is spent improving and adapting our processes, they become less efficient and costs of new developments also increase.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1160514029129895022006-10-10T21:42:00.000+01:002006-10-10T22:00:29.200+01:00C# collection classes performanceI was looking for a table summarizing how different C# generic and non-generic collection classes performed, relative to one another, thought there would be hundreds available, but could not find one. So here one is for my future reference, and for anyone else who reads this.<br /><br /><img src=http://www.richardjonas.com/images/collections.png><br /><br />O(1) = constant time<br />O(log n) = time proportional to the log of the number of elements in the collection<br />O(n) = time proportional to the number of elements in the collection<br /><br />Some collections are better for smaller collections, but don't scale to larger ones. The List, LinkedList, SortedList, Queue and Stack classes are better for smaller collections than the Dictionary, Hashtable and SortedDictionary classes.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1159954288319570842006-10-04T10:25:00.000+01:002006-10-04T10:31:28.330+01:00The type or namespace name 'Properties' could not be foundI was getting an error message when building my project that said "The type or namespace name 'Properties' could not be found".<br /><br />This was because I had changed the default namespace in the properties for my project to make it "project.name" instead of "name". The class that did not build was already in the namespace "project.name".<br /><br />The error message was on a line that said <br /><br />"global::name.Properties.Resources...."<br /><br />Changing this to<br /><br />"global::project.name.Properties.Resources...." <br /><br />seemed to fix the problem.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1158226618132136932006-09-14T10:23:00.000+01:002006-09-14T10:36:58.143+01:00Export to excel from SQL Server ExpressOnce upon a time, a big bad grizzly bear wanted to write a program to export a view from an SQL Server Express database (containing the names and addresses of sweet fluffy things he wanted to eat) to an Excel file. As this was SQL server express, he tried to use DTEXEC and integration services, but growled ferociously when he realised that integration services was not supplied with excel, promising to sharpen his claws and tear apart Bill Gates. <br /><br />However, a passing raccoon came to his rescue, and told him about the following trade secret way to do this (subject to removing the raccoons name and address from his database):<br /><br />1) Go to the Surface Area configuration tool, select "Surface Area configuration for features". Select "Ad Hoc Remote Queries", and turn on "Enable OPENROWSET and OPENDATASOURCE support".<br /><br />2) Create a template excel file, with the first row containing the column names in your view. You can use integration services to export a file to Excel, and then delete the data from it, leaving the first row.<br /><br />3) From your program, use the File.Copy command to copy the template file to your destination file.<br /><br />4) Run the following SQL query to populate the Excel file<br /><br />insert into OPENROWSET('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;Database=c:\\aaa.xls;', 'SELECT * FROM [Query]') select * from ExportView<br /><br />where c:\\aaa.xls is your file name, "Query" is the name of your worksheet and "ExportView" is the name of your table or view you want to export.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1155299887973384982006-08-11T12:54:00.000+01:002007-04-06T09:42:29.813+01:00Shrinking an SQL Server 2000 Transaction LogI have a database in which the transaction log grew to 19GB, taking up the entire disk space on the server it was on, and which could not be shrunk. Most of the things I found on the net didn't shrink this very much. <br /><br />However, I found the following script here which worked well, reducing it from 19GB to 52 MB.<br /><br /><a href=http://www.thescripts.com/forum/thread79839.html target=_blank>http://www.thescripts.com/forum/thread79839.html</a><br /><br /><pre><br />use database_name<br />go<br />create table shrinkfile(<br />col1 int,<br />col2 char(2048)<br />)<br /><br />dump tran database_name with no_log<br />dbcc shrinkfile(logical_name_of_log, 50, TRUNCATEONLY)<br />go<br /><br /><br />set nocount on<br />declare @i int<br />declare @limit int<br /><br />select @i = 0<br />select @limit = 10000<br /><br />while @i < @limit<br />begin<br />insert into shrinkfile values(@i, 'Shrink the log...')<br />select @i = @i + 1<br />end<br /><br />drop table shrinkfile<br /></pre>Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.comtag:blogger.com,1999:blog-9924016.post-1155193460814740552006-08-10T07:57:00.000+01:002006-08-10T08:04:20.823+01:00Updating .NET user controls on the screenI have some user controls that I need to add a lot of data to. This can be slow as the screen display is updated when each item of data is added. It also makes the dislpay flicker.<br /><br />I couldn't find an equivalent of the BeginUpdate and EndUpdate functions in .NET 2.0, but it is possible to call the Windows API functions as follows.<br /><br /><pre><br />private const int WM_SETREDRAW = 11;<br /><br />[System.Runtime.InteropServices.<br />DllImport("user32.dll")]<br />static extern bool SendMessage(IntPtr <br />hWnd, Int32 msd, Int32 wParam, Int32 <br />lParam);<br /><br />/// <summary><br />/// Stop updates while we are <br />/// filling a control with data<br />/// </summary><br />protected void BeginUpdate()<br />{<br /> SendMessage(this.Handle, WM_SETREDRAW, 0, 0);<br /> Cursor.Current = Cursors.WaitCursor;<br />}<br /><br />/// <summary><br />/// Restart updates<br />/// </summary><br />protected void EndUpdate()<br />{<br /> SendMessage(this.Handle, WM_SETREDRAW, 1, 0);<br /> if (Parent != null)<br /> {<br /> Parent.Invalidate(true);<br /> }<br /> Cursor.Current = Cursors.Default;<br />}<br /></pre><br /><br />I included these in a base class used by all my user controls, and added code to change the cursor to a wait cursor whilst the control was updating.Richard Jonashttp://www.blogger.com/profile/14997733754093048669noreply@blogger.com