Tuesday, June 10, 2008

Photos from Tech Ed IT Pros: Bob Muglia Keynote, part I

My first batch of snapshots from Bob Muglia's keynote this morning, including a selection of programmatically stitched panoramas.

IMG_8455
IMG_8360 Stitch
IMG_8108 Stitch
IMG_7994
IMG_8012

IMG_8084 IMG_7977 IMG_7970

IMG_8271
IMG_8299

IMG_8280

IMG_8308

IMG_8246

IMG_8248

Comments: Post a Comment
Links to this post

Sunday, June 08, 2008

Photos from TechEd 2008 Devs: Party at Universal Studios Orlando

Copy of IMG_7239 Stitch
This panorama comprises five horizontal photos.
(Somewhere, Encarta's copy chief is smiling. Even after all these years, I remember the ESG's recipe: "pancake batter comprises butter, milk, eggs.")

 

IMG_7261
 
IMG_7316 Stitch2
 

 

IMG_7253 Stitch
This very weird panorama comprises six horizontal photos.
It isn't totally successful but it's sure fun to look at.

 

 

IMG_7289
 

IMG_7308
 

 

IMG_7329
 

 

Labels: , , ,

Comments: Post a Comment
Links to this post

Photos from Tech Ed 2008 Devs: Carl Franklin plays the show floor

Sunday now and I'm finally finding time to catch up on all the pictures I shot during Tech Ed Developers last week. The co-host of .NET Rocks!, Carl Franklin has a fine voice and plays guitar with exceptional skill.  Many of us milling the conference floor ceased our schwag-collecting and stopped by to hear Carl play.

 

IMG_7127

IMG_7119 Stitch 

 

IMG_7088

 

IMG_7112 IMG_7130 IMG_7101 IMG_7133

 

 

IMG_7156

Labels: , , ,

Comments: Post a Comment
Links to this post

Tuesday, June 03, 2008

Microsoft Tech Ed 2008 Developers | Panoramic images from Bill Gates' keynote

Programmatically stitched panoramic images. I shot these pictures during Bill Gates' keynote on Day 2 of Microsoft Tech Ed 2008 Developers.

IMG_7030 Stitch
Empty. Stitched from ten vertically-shot images.

IMG_6641 Stitch
Full! Stitched from six vertically-shot images.

IMG_6649 Stitch
billg takes the stage. Stitched from ten vertically-shot images.

IMG_6668 Stitch

IMG_6964 Stitch
Lineup for the Q&A with billg

IMG_6967 Stitch (2)

Quizzing Mr. Gates.

IMG_6709 Stitch
This one's an uncropped mess but I sort of like it anyway. Next year maybe I'll bring a full-frame fisheye lens to shoot the keynote.

General call to conference organizers on technology topics: I am happy to exchange unrestricted rights to the thousands of photos I invariably shoot at these events for comps on conference registration fees.

Labels: , , ,

Comments: Post a Comment
Links to this post

Tech Ed 2008 Photographs | Monday | Jeff Prosise and Panoramas

I returned to Tech Ed 2008 Developers determined to take a picture or two. I took the photographs below during Monday's pre-conference sessions. Many of the images below were programmatically stitched into panoramas from several pictures, a technique I've been playing with recently to communicate the scale of things and to combat the grain associated with shooting handheld in low light.

IMG_6352
Inside: Orange County Convention Center entrance.

IMG_6467
Outside: Orange County Convention Center entrance.

IMG_6340 copy
Most denizens of the IT world will appreciate this bus-borne commentary on organizational teamwork. Nice to start Tech Ed with a smile.

IMG_6342_crop
Colors!

IMG_6379

IMG_6380

IMG_6407

IMG_6427

IMG_6432

Jeff Prosise hard at work during his Silverlight PreCon.


IMG_6417
Jeff Prosise

IMG_6445_crop
Jeff Prosise, looking contemplative as he confronts the existential crisis of Q&A.

Copy of IMG_6399
Jeff Prosise with us Q&A groupies

IMG_6475 Stitch
Orange County Convention Center at dusk. This panorama comprises eight vertically-shot images. I'm not satisfied with this -- but I've got the rest of Tech Ed Devs and Tech Ed IT Pros to do better!

IMG_6504
Comments: Post a Comment
Links to this post

Wednesday, October 17, 2007

Ken's Oct. 14 Long Beach Marathon: 3:30:19

Exactly one month after my first marathon in Maui (which I finished in a relaxing 3:48) I ran closer to home in the Oct. 14 Long Beach Marathon. Dr. Fine joined me on this adventure: me on foot, Essie snapping pictures and cracking encouraging jokes from her bicycle the whole way (example: "Don't hold back, Ken! Remember, I know CPR!!!")

Blogging provides a nice look back at the journey. Way back in March I posted pictures from my first training runs in San Francisco, and using Gmap-Pedometer I quickly established the routes that would become the core of my training (Costa Mesa to Newport Pier, Costa Mesa to Huntington Pier, Costa Mesa to chocolate bananas on Balboa ... ) 

Kudos to the organizers of the Long Beach Marathon: it was a super well-planned and well-executed event, a beautiful course, and a whole lot of fun. I thought it was especially great how they thawed Elvis from his cryogenic storage to cheer us on (pictured below).  I will be back for more running fun at Long Beach next year.

The stats for the first printing of my trading cards...

Pace: 8:02 per mile / 3:30:19 total chip time
Place overall: 171 out of 2343
Place among men: 152 out of 1462
Place in my age group (35-39): 29th out of 243

I'm still well off of a Boston qualifying time of 3:15:59, but I'm sure that with enough time and practice, I'll get to that pace and better. Most important: I'm very much enjoying these stabs at amateur athleticism. Try.

n539469574_375042_4147 n539469574_375122_1637

n539469574_375041_8859

Comments: Post a Comment
Links to this post

Saturday, July 21, 2007

example | C# .NET ASP.NET | Writing a directory's contents as XML, and binding that XML to an ASP.NET databound control

Intent: Write an XML file that describes each file in a directory, and then use that XML file as a datasource for an ASP.NET databound control.

Discussion: .NET has high-level abstractions for creating XML in the form of the XmlTextWriter object. It is fairly easy to use.

Overview: Instantiate a DirectoryInfo Object. Instantiate a FileInfo array by calling the .GetFiles on your instantiated DirectoryInfo object. Instantiate a MemoryStream object. Instantiate an XmlTextWriter object and set its character encoding to UTF-8. Initate a foreach loop over the FileInfo[] array, instatiating a fileInfo object on each iteration of the loop. To open a new element and populate it, call XmlTextWriterObject.WriteStartElement, then call XmlTextWriterObject.WriteString  to assign the content of the element, and then call XmlTextWriterObject.WriteEndElement() to close it. Note that elements can be nested; be sure to call the .EndElement() method at the appropriate place for your nest. Write the finished Xml to a file by instantiating a FileWriter object, calling OpenWrite(Filename), instantiating a byte[] array and calling the MemoryStream.ToArray() method, and finally calling the FileStream.Write() using the byte array as a parameter of the method. Once the XML is written, specify it as an XmlDataSource by assigning the byte array to the XmlDataSource.Data property and calling the XmlDataSource.DataBind() method. (whew!)

Weaknesses: I'd like to know how to avoid writing the Xml to a temporary file, as shown below. How can this all happen in memory?

 

   protected void ShowPhotoGrid( string jobID)
{

DirectoryInfo dir = new DirectoryInfo(@"R:\whatever\"+jobID);
FileInfo[] fis = dir.GetFiles("*ld200.jpg");
//FileInfo fi = new FileInfo();

MemoryStream s = new MemoryStream();
XmlTextWriter xw = new XmlTextWriter(s,Encoding.UTF8);
xw.WriteStartDocument();
xw.WriteStartElement("filesystemitems");
string largefilename = "";

foreach (FileInfo fi in fis)
{
xw.WriteStartElement("filesystemitem");
xw.WriteStartElement("filename");
xw.WriteString(fi.Name);
xw.WriteEndElement();
xw.WriteStartElement("filenameandpath");
xw.WriteString("http://whatever.org/content/whatever/" + jobID +"/" + fi.Name);
xw.WriteEndElement();
largefilename = StringManipulation.LeftOfRightmostOf(fi.Name, '_');
largefilename = (largefilename + "_ld600_watermark.jpg");
xw.WriteStartElement("filenameandpathlarge");
xw.WriteString("http://whatever.org/content/whatever/" + jobID + "/" + largefilename);
xw.WriteEndElement();
xw.WriteStartElement("filesize");
xw.WriteString(Convert.ToString(fi.Length));
xw.WriteEndElement();
xw.WriteEndElement();
}
xw.WriteEndElement();
xw.Flush();

// Write memorystream to a file. This is not the most efficient way to do this. What's better?
FileStream fs = File.OpenWrite(@"R:\whatever\blahblah.txt");
byte[] data = s.ToArray();
fs.Write(data, 0, data.Length);
fs.Close();

// Convert the data array to a string and response.write it
string myString = System.Text.Encoding.UTF8.GetString(data);
// Response.Write(myString);


XmlDataSource1.Data = myString;
XmlDataSource1.DataBind();
DataList1.DataBind();

}
//???? How do I convert my MemoryStream object to a string
        // It involves Writing the MemoryStream to a byte array, and converting it to a string, but I can't get things working quite right
}
Comments: Post a Comment
Links to this post

example | C# .NET ASP.NET| Binding image names from a filesystem to an ArrayList, and binding that to ASP.NET databound control

Intent: Sometimes you want to display photographs contained in a filesystem directly, without referencing  an intermediate data layer like a database store or XML file. You

Overview: Instantiate an ArrayList. Iterate over the output of the Directory.GetFiles() method, specifying the image extension as a mask. Build up HTML that should be placed in each cell of a databound control. Call the ArrayList's .Add method to write the HTML string to the ArrayList. Assign the Array as the DataSource of a DataList.  Bind that DataList to an <ItemTemplate> using the <%# Container.DataItem %>    syntax.  Call the DataList.DataBind(); method.

Discussion: The example below also allows the user to adjust the number of displayed columns via a DropDownList selection. This works by programmatically assigning the DataList.RepeatColumns property to the DropDownList.Selected property. 

        ArrayList pics = new ArrayList();

string code;
string image;
//string myFile;
foreach (string myFile in Directory.GetFiles(("T:\\WHATEVER\\WhateverSubDir"), "*.jpg"))
{
image = YOUR_DIRECTORY + Path.GetFileName(myFile);
code = "<img src=\"" + image + "\">";
code += "<br /> " + Path.GetFileName(myFile);
pics.Add(code); // add the image to your ArrayList
}
// Bind the pics to a DataList
dlImages.DataSource = pics;

dlImages.RepeatColumns = Convert.ToInt32(DropDownList1.SelectedValue);
dlImages.DataBind();
 
    <form id="form1" runat="server">
<div>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True">
<asp:ListItem Value="1">One column</asp:ListItem>
<asp:ListItem Value="2">Two Columns</asp:ListItem>
<asp:ListItem Value="3">Three Columns</asp:ListItem>
<asp:ListItem Value="4">Four Columns</asp:ListItem>
</asp:DropDownList>
<asp:DataList ID="dlImages" runat="server" RepeatColumns="5" RepeatDirection="Horizontal">
<ItemTemplate>
<%# Container.DataItem %>


</ItemTemplate>
<ItemStyle Font-Names="Arial" Font-Size="X-Small" />
</asp:DataList></div>
</form>
Comments: Post a Comment
Links to this post

example | C#, .NET, EntitySpaces | Testing whether an item is already in the database

Intent: Using the EntitySpaces ORM framework, test whether an item exists in a database or not. The example below shows a test of whether a "tag" appears in the database.

Overview: Write a function which accepts the item to test as a string parameter.  Instantiate an EntityCollection. Execute an ES Query  on that collection, using the Like operator and using the tag string as the parameter. Execute the ES .Load() method to load all available items into a collection. Run a comparison operation on whether Entity.Count is greater than or equal to one. If you wish to return a property of the found items, iterate over the EntityCollection using foreach, instantiating a single item within the collection on each loop. Return the property of the found item if you wish.

Discussion: Useful if you want to enforce single entries to a database table. The tags example below is a good application of this: you want to build a directory of categorical tags and list them only once, referencing the single tag many times using a Join table.

 

    public int IsTagInDatabase(string tagToCheck)
{
TagsCollection tagcoll = new TagsCollection();
tagcoll.Query.Where(tagcoll.Query.Name.Like(tagToCheck.ToLower()));
tagcoll.Query.Load();
int tagID = 0;
if (tagcoll.Count >= 1)
{

foreach (Tags tag in tagcoll)
{
tagID = Convert.ToInt32(tag.Tagid);
}
return tagID;
}
else
{
return 0;
}
}
Comments: Post a Comment
Links to this post

example | C# .NET | Isolating a directory that DOES or DOES NOT contain a particular substring

Intent: This is useful in instances when you have a highly organized archive with different, similarly-named directories in them, e.g. FolderNameRAW and FolderNameTIF

Overview:   Declare a string array using the Directory.GetDirectories() method. Iterate over each string in the array. Use the string.IndexOf method to  isolate the substring of interest. Execute a comparison, with a result of >= 1 meaning that the substring is found, and a comparison of == -1 indicating that the substring was not found. 

 

   string[] dirs = Directory.GetDirectories(sourceImageDirBase);

foreach (string dir in dirs)
{
if (dir.IndexOf("RAW") >= 1)
{
                    // Do something here to images that DO have the string RAW as part of their name
}

{
if (dir.IndexOf("RAW") == -1)
{
                    // Do something here to images that DO NOT have the string RAW as part of their name
                    }

}

}
Comments: Post a Comment
Links to this post

Wednesday, March 21, 2007

Emulating max-width in IE

Great little article concerning how to constrain the maximum width of text columns in IE to a specified pixel width, while still offering users the ability to scale the page more narrowly if necessary. Many versions of IE do not properly implement max-width and so modern CSS2- based solutions are out. On to the hackery:

http://www.svendtofte.com/code/max_width_in_ie/ (the great little article)
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/overview/recalc.asp (MSFT page on dynamic properties)


The meat for my purposes (read the original article; it has many implementations that may serve you better):

<html>
<style>
body {
width:100%;
margin:0;
padding:0;}

p {
border:1px solid red;
max-width:800px;
width:expression(document.body.clientWidth > 800? "800px": "auto" );
}
</style>

Somewhat predictably, these hacks don't work at all in HTML mail, which is unfortunate given that's where I wanted to implement it. However, they don't break things either, which is nice for the purposes of webpages that live dual lives as standalone pages and components of multipart mails. My understanding is that max-width is implemented in Outlook 2007 along with a bunch of other CSS properties. By 2019 or so I imagine be able to confidently implement this when we aren't being deservedly chased around by unhappy  Replicants.


Technorati tags: , , , ,
Comments: Post a Comment
Links to this post

Friday, March 16, 2007

VS.NET 2005 Basics, Part II: Shortcut Keys

Keep your hands on the keyboard, and you will work with agility. Short list of the best/most useful VS.NET 2005 shortcut keys, plagarized from everywhere:

MAJOR WINDOWS AND TOOLBOXES
Ctrl + Alt + S
= Server Explorer
Ctrl+Alt+A = Command Window
Ctrl+Alt+O = Output Window
Ctrl+Alt+T = View Document Outline
Ctrl+Alt+I = Immediate window, evaluate expressions and execute individual commands
Ctrl + Alt + X = Toolbox
Ctrl+ Alt + K = Task List
Ctrl-K, Ctrl-B - Open Code Snippet manager
F4 = Properties Window
Shift + F4 = Property Pages
Ctrl + Shift + C = Class View
Ctrl + Shift + E = Resource View
Ctrl + Alt + C = Call Stack
Ctrl + Alt + V, L = Locals

NAVIGATING CODE
Ctrl-Minus
= Takes you backward to the last section of code you were looking at
Ctrl-Shift-Minus = Takes you forward to the next section of code in your history.
F12  = Jump  to definition. On a method, it will navigate back to its source. On an overloaded method, you'll be presented with pop-up window that cues you for which method signature you had in mind. Duplicates the (slower-to-use) context menu.
Ctrl + I = Incremental Search Down
Ctrl + Shift + I = Incremental Search Up
Ctrl + D = Go to find Combobox
Ctrl + Shft + F = Find in Files
F8 - Move to next item. Works in many windows, e.g. the task list.
Ctrl+] = Bounce cursor between balancing braces/parens

SNIPPETS
Ctrl-K, Ctrl-B - Open Code Snippet manager

OUTLINING
Ctrl-M, Ctrl-O
= collapse all outlines
Ctrl-M Ctrl-L = expand all outlines
Ctrl-M, Ctrl-M = expand a specific outline section

MAKING SENSE OF INTELLISENSE
Ctrl-Shift-Space
= Restore Intellisense parameter window. Useful if you "disappear" it via mouse or keyboard input.
Ctrl-J = List members. Restores what you normally get when you hit "." after an object instance

CLEANING UP YOUR CODE
Ctrl-A Ctrl-K Ctrl-F
  = Reformat page
Shift-Enter  = insert new blank line above current line
Ctrl-Shift-Enter = insert new blank line below current line
Ctrl-T = transpose the two characters the cursor between current cursor position
Ctrl-Shift-T = transpose words in current cursor position

WINDOWING AND VIEWS
Crtl+Tab
= switch between windows inside the current project
Alt+Space, N = Minimize current application
Alt+Space, X = Maximize current application
Alt+Space, R = Restore current application
Shift+ALT+Enter =  Full screen mode.  Good for laptop dev.
CTRL+R, CTRL+R = Toggle Word wrap.
Ctrl+ F4 = Close active code windows in project
Number pad *  = Expand all in the Solution Explorer
Number pad -  = Collapse all in the Solution Explorer
Alt+W, L = Close all windows

COMMENTS
Ctrl+K, Ctrl+C
= Comment out the current selected section
Ctrl+K, Ctrl+U = Uncomment the current selected section

BOOKMARKS
Ctrl-K Ctrl-K
= Set/unset bookmark in current position
Ctrl-K Ctrl-N = Navigate to the next bookmark

CODE VIEW/DESIGN VIEW
Shift+F7
= show designer window
F7 = show code window

Ctrl+PageDown = Toggle between source and design views in .aspx files (yessssss!)

MSDN HELP
Ctrl + Alt + F1
= View Contents Tab
Ctrl + Alt + F2 = View Index Tab
Ctrl + Alt + F3 = View Search Tab
Ctrl + Alt + F = View Favorites Tab
Shift + Alt + F3 = Search results
Shift + Alt + F2 = Index results

BUILDING AND DEBUGGING
Ctrl+Shift+B
= Build solution
F9 = Toggle Breakpoint
F5 = Start
Shift + F5 = Stop Debugging
Ctrl + F5 = Start Without Debugging
F11 = Step Into
Shift + F11 = Step Out
F10 = Step Over
CUT, COPY, 'N PASTE
Cntl+C
(with nothing selected) = copy entire line
Ctrl+Enter = copy line above

Comments: Post a Comment
Links to this post

VS.NET 2005 Basics Part 1: XML Documentation, Intellisense, and automatic documentation generation

XML documentation is an insanely great feature of Visual Studio.  

Why? In a word, Intellisense. If you're a total newbie, welcome. Intellisense is simply a collection of informational popup windows that appear while you're programmming, and these popups contain extremely useful information relating to the code you are trying to write. Intellisense saves time, jogs your memory, and helps you write code accurately. If you have written or have inherited a complex hierarchy of reusable programmatic classes, Intellisense will help you remember the organization and needs of that class structure.

If you document your code using VS.NET's simple XML-based tagging, you'll be continually prompted with Intellisense windows with information about what your code does. You can integrate your own writing and documentation into the experience of working with the VS.NET tool. This is so powerful.

 A few examples and screenshots will really help explain things here.

Long ago I wrote a class called "FileOps," which is a grab-bag of very useful functionalities (methods AKA functions) relating to file operations on our web application server. I commonly use these methods in my web application work, so I've put the FileOps class in a subfolder of my App_Code folder so it is available to be used by any of my applications.

One of the methods (functions) in that class is CreateYearAndMonthDirectoryBasedOnDate(). This method creates and helps maintain an organized file structure on our server's file system, arranging it in a useful hierarchy similar to the folder structure illustrated below:

Let's have a look at some of the code for that method now. The code includes a bunch of comments structured as XML, positioned just prior to the code that defines the method. These comments document different aspects of the method's operation, including its parameters (inputs) and return type (output.) Structuring your documentation in this particular way is extremely useful if you're working in Visual Studio. We'll soon find out why.

   /// <summary>
/// <para>Creates a hierarchical folder structure corresponding to a year and month on a server filesystem, e.g.</para>
/// <para></para>
/// <para>c:\basePhysicalDirectory\2007\July\</para>
/// <para></para>
/// <para>You can subsequently copy files into these folders, creating an automatically organized folder structure. </para>
/// <para>If the folder already exists, then it will simply return the path to the existing directory.</para>
/// </summary>
/// <param name="inputDate">DateTime upon which to base the creation of the new folder</param>
/// <param name="basePhysicalDirectory">The base physical directory on the server filesystem that will be used to create the year and month folders.</param>
/// <returns>Returns a string corresponding to the newly created (or existing) path on the server filesystem.</returns>
public static string CreateYearAndMonthDirectoryBasedOnDate(DateTime inputDate, string basePhysicalDirectory)
{
string yearDirectory = Path.Combine((basePhysicalDirectory), ((inputDate.ToString("yyyy")) + @"\"));
string monthDirectory = Path.Combine(yearDirectory, ((inputDate.ToString("MMMM")) + @"\"));

if (!Directory.Exists(monthDirectory))
{
if (!Directory.Exists(yearDirectory))
{
System.IO.Directory.CreateDirectory(yearDirectory);
[etc.]


"So what?" say the cynics. "It's just a bunch of code comments as XML. Big deal." Well... the Good Part comes two weeks or two years later, when I'm trying to use my handy FileOps class in other programming projects. What follows is my view from Intellisense as I call the FileOps class's methods to do some useful work. Below, I'm saving out a programmatically created PDF file, and I want it to be filed in an organized way. I use CreateYearAndMonthDirectoryBasedOnDate() to generate a folder structure on the server based on a database entry associated with the PDF. What I want you to pay attention to here is how VS.NET uses Intellisense and the XML documentation I wrote for the method to give the programmer a step-by-step cue of what she should be doing next.



 
(Step 1: As I type "FileOps", the name of my class, notice I'm presented both a selectable list of all of the classes available to me, and a yellow comment box. The comment box includes an XML comment I wrote that describes the entire "FileOps" class. (Interested in the database abstraction code? Check out the sublime  EntitySpaces Object-Relational Mapping framework ))



 
(Step 2: As I hit the period ".", which denotes the fact that I want to call a method of my FileOps class, the previous Intellisense informational window disappears, and a selection of the methods I have written in the past and associated with FileOps pops up. Note that the XML documentation I wrote earlier to accompany my method is appearing as a comment in Intellisense. Very handy! Anything that reduces the amount of stuff the developer has to keep in her brain at once is a great thing.)
 
(Step 3: I continue typing and am now filling in the parameters that are required by my method. Remember how I described my parameters in XML documentation with the <param>...</param> tags? My context-specific documentation appears right here, right when I want to see it.)



 
(Step 4: When I reach the last parameter that my function requires, again it shows me the descriptive docs I wrote for what the parameter is and does. Sharper-eyed newbies will also notice that the datatype of the parameter is being indicated, which helps remind the finite and forgetful programmer what information the method requires to do its work.)



This is a deliberately simplified example involving straightforward static methods. For many people, Intellisense is old hat and reading "Run Dick Run" above may seem more than a little patronizing. However, I'm surprised how many otherwise smart developers out there don't use VS.NET's XML documentation to describe their classes or methods at all. Makes no sense. This stuff is great: context-specific information when you need it, and changeable as required with very little investment of time.  If you're rooting around for just the right web application technology to learn, Intellisense/VS.NET and this documentation stuff is in itself a compelling argument to take a serious look at ASP.NET.



This XML documentation can also be parsed by external tools and compiled into CHM (Microsoft Help) files, or sets of HTML pages. My understanding is that for a long time the de facto standard for this kind of tool was the free nDoc tool, but as of last summer NDoc is not being developed further. Microsoft is in the process of picking up the external documentation ball with SandCastle, and I imagine we'll see something like it in the next release of Visual Studio.



I'm going to underscore a few things that may not be obvious to VS.NET newbies and newbies at heart.



1) To document your code, get in the habit of hitting three slashes before front of any method, property, class, or other structures in your code files. VS.NET is smart and will figure out what comment types are relevant given where you're at in the code. If you've been hand writing <summary> ... </summary> or <param> ... </param> as XML comments as you've studiously followed some tutorial you picked up somewhere, you have been doing things the hard way. Enter three slashes, and let Visual Studio do the work of writing this cruft for you, including a summary section, a comment for each parameter, and a comment for the return type.



2) The VS.NET Task List is useful, and you can automatically add stuff to the Task List using TODO comments in the correct form. You would think that you might embed todo comments using the same XML patterns, e.g.



WRONG! <todo> Rewrite this method!</todo> WRONG!


This does not work the way you might think. Entering a comment in the following form will automatically place a TODO item on the task list:



//TODO: Rewrite this method. 


Summary of XML comment tags that are parsed by VS.NET
I'm going to borrow the Code Project's excellent, terse summary of tag types and comments about the tags for my own reference. The text below is courtesy of a great article at the Code Project that also describes how to set up NDoc to generate MSDN-style documentation from XML comments.



The summary tag is the most basic of tags. The list below is the complete set currently supported by VS.NET. The ones marked with a * are the ones I feel are the most useful and the ones we will be dealing in the following examples.

c
The c tag gives you a way to indicate that text within a description should be marked as code. Use code to indicate multiple lines as code.



code*
The code tag gives you a way to indicate multiple lines as code. Use <c> to indicate that text within a description should be marked as code.



example*
The example tag lets you specify an example of how to use a method or other library member. Commonly, this would involve use of the code tag.



exception*
The exception tag lets you specify which exceptions a class can throw.



include
The include tag lets you refer to comments in another file that describe the types and members in your source code. This is an alternative to placing documentation comments directly in your source code file.



para
The para tag is for use inside a tag, such as <remarks> or <returns>, and lets you add structure to the text.



param*
The param tag should be used in the comment for a method declaration to describe one of the parameters for the method.



paramref
The paramref tag gives you a way to indicate that a word is a parameter. The XML file can be processed to format this parameter in some distinct way.



permission*
The permission tag lets you document the access of a member. The System.Security.PermissionSet lets you specify access to a member.



remarks*
The remarks tag is where you can specify overview information about a class or other type. <summary> is where you can describe the members of the type.



returns
The returns tag should be used in the comment for a method declaration to describe the return value.



see
The see tag lets you specify a link from within text. Use <seealso> to indicate text that you might want to appear in a See Also section.



seealso*
The seealso tag lets you specify the text that you might want to appear in a See Also section. Use <see> to specify a link from within text.



summary*
The summary tag should be used to describe a member for a type. Use <remarks> to supply information about the type itself.



value*
The value tag lets you describe a property. Note that when you add a property via code wizard in the Visual Studio .NET development environment, it will add a <summary> tag for the new property. You should then manually add a <value> tag to describe the value that the property represents.



Resources:
Producing Professional MSDN-style Documentation with .NET and NDoc
http://www.devx.com/dotnet/Article/29646

C# and XML Source Code Documentation
http://www.codeproject.com/csharp/csharpcodedocumentation.asp



NDoc on SourceForge:
http://ndoc.sourceforge.net/



Insightful O'rielly article on NDoc and the problem of documentation generation in general:
http://www.ondotnet.com/pub/a/dotnet/2002/12/09/ndoc.html



Comments: Post a Comment
Links to this post

Saturday, March 10, 2007

Finding JPG image dimensions programmatically using ASP.NET/C#

.NET includes everything necessary to programmatically read the dimensions of image files such as .JPGs. This is useful in cases where you want to explicitly specify the size of an image at runtime. In my case, I had an image cropping control that  required I send the dimensions of the image to be cropped. The means to return image size in .NET is a bit verbose, but it is nice that you can do this without going to an external component or anything outside of what's baked into .NET. See below.

using System.Drawing;
using System.Text;
ImageCropper1.ImageUrl = "../../test8180-uweek mail prelim design.jpg";
string myDimensions = ImageProcessing.GetImageDimensions(@"c:\Inetpub\wwwroot\ni\test8180-uweek mail prelim design.jpg");
string[] dimensions = myDimensions.Split(new char[] {','});
string imageWidth = Convert.ToString(dimensions[0]);
string imageHeight = Convert.ToString(dimensions[1]);
ImageCropper1.Width = Convert.ToInt16(imageWidth);
ImageCropper1.Height = Convert.ToInt16(imageHeight);


Imageprocessing is  a custom class I wrote/stole: something old, something new, something borrowed, and something blue. It consists mainly of static methods, including the GetImageDimensions function called above:

    public static string GetImageDimensions(string fileNameAndPath)
{
System.Drawing.Image theImage = System.Drawing.Image.FromFile(fileNameAndPath);
float UploadedImageWidth = theImage.PhysicalDimension.Width;
float UploadedImageHeight = theImage.PhysicalDimension.Height;

string size = UploadedImageWidth.ToString() + "," + UploadedImageHeight.ToString();
return size;
}


Two things bug me. The first: the Krispware cropping control demands the following structure for the path to the image, at least on my local development machine:

        ImageCropper1.ImageUrl = "../../test8180-uweek mail prelim design.jpg";


In my case and on my machine, I found I could not use the typical "~/" pathing notation to the root; on the same page I placed an Image control and was able to use "~/" just fine. This could be caused by any of a number of things:

a) an inherent limit of the control
b) something funky that's specific to my dev machine, or
c) something funky with how the virtual directories were  set up on installation, which I don't really understand well. (Any help out there?)



Second question.  In the course of hacking around with this started to think, "wow, maybe I should write my own augmented image class that would bundle in loads of functionality  and allow capabilties like:

    KensCoolImageClass CoolImage = new KensCoolImageClass(); 
Coolimage.RenderAsCropControl();
Coolimage.RenderAsUserControl(300,200,"isZoomable" ...);
Coolimage.SendToFriend(mediumSize, "kenfine@u.washington.edu);
Coolimage.CropByCoords(22, 200,4, 400);
Coolimage.UpdateExifData("metadata1","metadata2,...);
Coolimage.PostToFlickr(encrypedAccountName, encrypedAccountPassword);
Coolimage.ResizeByPercentage(40);
Coolimage.Rotate(90, "clockwise");
int theHeight = Coolimage.Height;
int theWidth = Coolimage.Width;


I'm curious why some of these functionalities are not built into the framework itself: my code above works, but it seems a little more painful than should be necessary.


Labels: , , ,

Comments: Post a Comment
Links to this post

Thursday, March 08, 2007

The Run from Costa Mesa to Newport Pier in Pictures

Strong run. Left home around sunset-time and ran back on the Santa Ana Trail in darkness.

Running in the dark in a near-abandoned industrial wasteland may not be bright. My uncle-in-law Jerry swears that "they'll slit your throat!" but it hasn't happened quite yet.  

Some of the most fantastic runs I've had have been in the dark, at times and places responsible folks tell you not to go. I remember running through NYC's Central Park long after nightfall in 2005. Lovers shared benches, old Greek men perfumed the air with pipes. I ran fast, the summer night thick with stars and fireflies. 
My route from Costa Mesa to Newport Pier on Gmap Pedometer

 

 


  

 

 

            

 

 

 

 

Labels: ,

Comments: Post a Comment
Links to this post

Tuesday, March 06, 2007

The Run from Costa Mesa to Huntington Pier in Pictures

Dreary visions of yesterday's run from my cell phone camera. I like seeing what's possible with such limited equipment.

 

  

 

Labels: ,

Comments: Post a Comment
Links to this post

Sunday, March 04, 2007

Visions of the Golden Gate

Synthetic glimpses of an architectural masterpiece. Some of these photographs are elaborately manipulated in terms of levels (contrast) and perspective. The effect is disquieting: untidy humanity wiped away, leaving only clean abstractions. I'm uncomfortably reminded of the early works of a certain painter-turned-politician ...

I shot these pictures with my "running camera": an older Nikon Coolpix 995 that fits the hand like a baton.

 

 


 
 

 



 




 


 


 




 

 

Labels: ,

Comments: Post a Comment
Links to this post

Saturday, October 02, 2004

IMAGE AND REALITY : Marc-André Hamelin

Image...


...and reality. The authentic Hamelin walked onto Meany's black stage Thursday night, tux misplaced. He was clad in simple gray slacks and a casual shirt that might have been pulled from a country-western watering hole in Texas. Great green embroidered ribbons of foliage and threaded red roses graced Hamelin's shoulders. "Cool," Essie offered. Mr. Hamelin received my wife's good tidings and the audience's applause modestly.

Like every other performer I've seen at the "President's Piano" series at the University of Washington, Hamelin can play with the world's best. His first piece of the evening, Bach's "Chaconne from the Violin Partita in D minor" was affecting, but maybe that's just the insinuations of all the Hofstader I've been reading lately. Bach's piano stuff is very hard to play well, so I'm told.

Hamelin reminds me of Stephen Hough, who played like a god as the headliner of the President's Piano series two years ago. Like Hough, Hamelin's technique is immaculate. Also like Hough, Hamelin has a big bright creative mind hanging over those terrific hands. Both men performed some of their own compositions in the course of their performances. Hamelin's haunting "Music Box" evoked the quieting bells of rusting wind-up toys, the last dances of faded and tired things. Hamelin finished the piece with a long sigh, and Meany's full house spontaneously mumured its approval.

Labels:

Comments: Post a Comment
Links to this post