« September 2002 | Main | November 2002 »

October 31, 2002

.resx & .resource files, Form.Icon, Visual Studio treats first class in source file specially, fuslogvw

I tried to set the From Icon property for Windows.Forms application and got a MissingManifestResourceException. After spending too much time looking for complexities in the resource space, the problem turned out to be a probable Visual Studio .NET bug.

 

Form1.cs will automatically get a Form1.resx file which is an XML file containing the serialized resource values. The name of the compiled .resource file turns out to come from the full class name of the first class defined in the file! This is a problem if you’ve defined some helper class before your derived Form class. A simple work around is to move the derived Form class back to the top of the file.

 

typeof(object).Assembly – returns the assembly where the object’s type is defined.

Assembly Binding Log Viewer (FusLogVW) – shows what assemblies are actually loaded by a program and from where.

Putting the following in foo.exe.config allows referenced assemblies to be found in a private subdirectory “Stringer”.

<configuration>   
  <runtime>
    <assemblyBinding
       xmlns="urn:schemas-microsoft-com:asm.v1">
       <probing privatePath="Stringer"/>
    </assemblyBinding>
  </runtime>
</configuration>

October 30, 2002

First experience with machine.config file.

Machine.config, contains settings that apply to an entire computer. This file is located in the %runtime install path%\Config directory.

 

Machine.config contains configuration settings for machine-wide assembly binding, built-in remoting channels, and ASP.NET.

 

DataSet Merge, Master Details DataGrids, .xsd files, DataRelation, performance issues

Avoiding some really horrible performance with DataSet and DataGrid classes when following a pattern from the documentation for loading data which fills a temporary DataSet which is then Merged into the persistent DataSet. Merging more than a few hundred rows is dog slow.

 

I modified the .xsd file produced by dragging tables to a new file according to the pattern from the MasterDetails QuickStart sample. The key thing, I think, is that the generated .cs file defines a DataRelation between the Company and Job tables, “CompanyJobs”. By setting the DataMember property to “Company.CompanyJobs” instead of just “Job”, I get just the kind of linkage I expected. By controlling the DataMember property via a menu pick, the same DataGrid layout serves double duty.

 

It’s key to also use the data member string when obtaining a DataView object for the grid, for pick correlation for example.

 

October 21, 2002

MSDN multi-threading Windows Forms article.

Good multi-threaded Windows Forms article: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms08162002.asp

 

October 16, 2002

volatile can only be applied to static members

Are there undocumented restrictions on “volatile”. Tried making a bool class field volatile, but the compiler complained until I made the field static, then it worked.

October 10, 2002

Application properties sample values

When coding against properties that return path information, its rarely clear from the documentation just what path their talking about.

 

A typical sample value works great for me to relate the semantic description to what I know about the Windows environment.

 

Typical values of the Windows Forms Application properties:

StartupPath

"C:\Tone\kzDev\VSP\Job Blaster\Job Blaster\bin\Debug"

CommonAppDataPath

"C:\Documents and Settings\All Users\Application Data\Kizmet\JobBlaster\1.11.1013.35494"

CommonAppDataRegistry

{Microsoft.Win32.RegistryKey}    Name: "HKEY_LOCAL_MACHINE\Software\Kizmet\JobBlaster\1.11.1013.35494"

CompanyName

"Kizmet"

CurrentCulture

{System.Globalization.CultureInfo}

CurrentInputLanguage

{System.Windows.Forms.InputLanguage}

ExecutablePath

"C:\Tone\kzDev\VSP\Job Blaster\Job Blaster\bin\Debug\Job Blaster.exe"

LocalUserAppDataPath

"C:\Documents and Settings\tone\Local Settings\Application Data\Kizmet\JobBlaster\1.11.1013.35494"

MessageLoop

true

ProductName

"JobBlaster"

ProductVersion

"1.11.1013.35494"

SafeTopLevelCaptionFormat

"{1} - {0} - {2}"

StartupPath

"C:\Tone\kzDev\VSP\Job Blaster\Job Blaster\bin\Debug"

UserAppDataPath

"C:\Documents and Settings\tone\Application Data\Kizmet\JobBlaster\1.11.1013.35494"

UserAppDataRegistry

{Microsoft.Win32.RegistryKey}    Name: "HKEY_CURRENT_USER\Software\Kizmet\JobBlaster\1.11.1013.35494"

 

 

October 09, 2002

MSDE, database distribution, osql command line tool.

osql is the simple command line tool for processing .sql files.

An existing database can be emptied, shrunk, detached and then connected with a connection string such as:

data source=PELL\VSDOTNET;AttachDBFilename=c:\tone\kzdev\vsp\jobsearch\jobsearch0.mdf;initial catalog=JobSearch;integrated security=SSPI;persist security info=False;workstation id=localhost;packet size=4096

 

A very simple batch file for running osql:

@echo on

set server=PELL\VSDOTNET

set newdbname=JobSearch

osql -e -d master -S %server% -E -Q "create database %newdbname%"

osql -e -d %newdbname% -S %server% -E -i "JobSearch.sql"

 

 

October 07, 2002

Simple EventLog entry writing

The following one-liner writes to the Application event log in both debug and release modes. The documentation does a great job of making it seem much more complicated…until you notice that half the overloads for WriteEntry are static:

 

EventLog.WriteEntry("Kizmet.Test", String.Format("This is a test."));

 

A “source” is an arbitrary string which will appear prominently in the event log’s event list view. A source can be registered which allows you to specify exactly which log you want to write to and is presumably a great idea for high volume logging. A source will automatically be registered with the Application log if it is used to write an event before being registered.

 

October 04, 2002

TextBox.Lines property makes a deep copy on both set and get.

Its odd that such a key aspect of knowing how to use a control correctly has to be determined experimentally, but there it is:

 

TextBox.Lines property makes a deep copy on both set and get.

 

Understanding Windows Forms layout and Dock behavior.

When laying out forms, the behavior of docking (& anchoring?) depends on the “depth” of the control. An “in-front” control will respect the boundaries of controls behind it when docking. An “in-back” control will ignore controls in front of it when docking.

 

There doesn’t appear to be an explicit way to tell what the depth of a control is.

 

The context menu has move forward/backward commands on it.

 

New controls are in-front of old controls.

October 02, 2002

DataGrid, ArrayList, Threads

Converted the JobSearchDesignerOnly project to use a second Thread for the Spider. Turned out to be easier than expected. The only trick was in the CrawlResultsEventHandler which returns a results summary of each page crawled. With the Spider running on its own thread, the first event handler would violate the Windows.Forms STA threading model if it tried to directly update the GUI, so the event is redirected by a BeginInvoke call to a second delegate which runs on the controls thread. Worked like a charm. There’s also some complexity around making sure the thread gets cleaned up and only started once the GUI is up. See JobSearchControls.SpiderPanel.cs.

ArrayLists of objects with public properties only sort-of works with DataGrids. I could find no way of having the grid update when results where added to the ArrayList. Switched to DataTable and DataView and everything works like a charm.

Put the GUI for the Spider results in a UserControl with a WebBrowser and DataGrid on it. This is definitely the way to build hunks of UI.

KzDataGrid derives from DataGrid and adds support for automatic column width adjustments, but only when using DataTableStyles.

Finally figured out how to inhibit the “AddNew” row in a DataGrid bound to a DataSet:

((DataView)((CurrencyManager) jobDataGrid.BindingContext[dataSet, "Job"]).List).AllowNew = false;

The List member returns the object which implements the IList interface, which in the case of a DataSet will be a DataView. The BindingContext of the data for the grid will be handled by a CurrencyManager, the alternative PropertyManager only handles single values.

October 01, 2002

SHDocVw, Microsoft Web Browser ActiveX Control

c:\Windows\System32\SHDocVw.dll is the Internet Explorer rendering engine. It can be added to the dotNET toolbox where it shows up as “Explorer”.

 

Silent property inhibits complaining about script errors.

 

A HandleCreated event handler coupled with testing the Handle property against IntPtr.Zero should be used as a gate on the first call to Navigate.

ActiveX interop & aximp.exe tool.

A wrapper has to be created for an ActiveX control before it can be used. This can be done manually by declaring C# classes with the appropriate attributes. The easy way is to use aximp.exe, when it works.

 

aximp.exe can be used manually, in which case you add references to the generated Foo.dll and AxFoo.dll manually, or automatically, by customizing the toolbox with a reference to the control and then dragging it onto a form. In this case the dll’s are named AxInterop.SHDocVw.dll and Interop.SHDocVw.dll.

If you only add a reference to the COM control to the project’s references folder, things don’t seem to work.