Share This!

Wednesday, May 28, 2008

Reconsidering Tables

My blog layout was all CSS. Then I made a simple change and suddenly the blog content started rendering below the sidebar for Firefox only. I started monkeying with the stylesheet and noticed a lot of "fixes" for certain behaviors in IE or Netscape or Firefox.

That's when it hit me. The whole "css, not tables" movement is a false religion, whose promises are nothing but a pipe-dream. Tables behave in a predictable way on every browser. Divs do not.

Easy SQL to Insert the states and territories into a Lookup Table

This has been tested in MSSQL.
truncate table states;

--STATES
INSERT INTO states (state, st) VALUES('ALABAMA','AL');
INSERT INTO states (state, st) VALUES('ALASKA','AK');
INSERT INTO states (state, st) VALUES('ARIZONA','AZ');
INSERT INTO states (state, st) VALUES('ARKANSAS','AR');
INSERT INTO states (state, st) VALUES('CALIFORNIA','CA');
INSERT INTO states (state, st) VALUES('COLORADO','CO');
INSERT INTO states (state, st) VALUES('CONNECTICUT','CT');
INSERT INTO states (state, st) VALUES('DELAWARE','DE');
INSERT INTO states (state, st) VALUES('DISTRICT OF COLUMBIA','DC');
INSERT INTO states (state, st) VALUES('FLORIDA','FL');
INSERT INTO states (state, st) VALUES('GEORGIA','GA');
INSERT INTO states (state, st) VALUES('HAWAII','HI');
INSERT INTO states (state, st) VALUES('IDAHO','ID');
INSERT INTO states (state, st) VALUES('ILLINOIS','IL');
INSERT INTO states (state, st) VALUES('INDIANA','IN');
INSERT INTO states (state, st) VALUES('IOWA','IA');
INSERT INTO states (state, st) VALUES('KANSAS','KS');
INSERT INTO states (state, st) VALUES('KENTUCKY','KY');
INSERT INTO states (state, st) VALUES('LOUISIANA','LA');
INSERT INTO states (state, st) VALUES('MAINE','ME');
INSERT INTO states (state, st) VALUES('MARYLAND','MD');
INSERT INTO states (state, st) VALUES('MASSACHUSETTS','MA');
INSERT INTO states (state, st) VALUES('MICHIGAN','MI');
INSERT INTO states (state, st) VALUES('MINNESOTA','MN');
INSERT INTO states (state, st) VALUES('MISSISSIPPI','MS');
INSERT INTO states (state, st) VALUES('MISSOURI','MO');
INSERT INTO states (state, st) VALUES('MONTANA','MT');
INSERT INTO states (state, st) VALUES('NEBRASKA','NE');
INSERT INTO states (state, st) VALUES('NEVADA','NV');
INSERT INTO states (state, st) VALUES('NEW HAMPSHIRE','NH');
INSERT INTO states (state, st) VALUES('NEW JERSEY','NJ');
INSERT INTO states (state, st) VALUES('NEW MEXICO','NM');
INSERT INTO states (state, st) VALUES('NEW YORK','NY');
INSERT INTO states (state, st) VALUES('NORTH CAROLINA','NC');
INSERT INTO states (state, st) VALUES('NORTH DAKOTA','ND');
INSERT INTO states (state, st) VALUES('OHIO','OH');
INSERT INTO states (state, st) VALUES('OKLAHOMA','OK');
INSERT INTO states (state, st) VALUES('OREGON','OR');
INSERT INTO states (state, st) VALUES('PENNSYLVANIA','PA');
INSERT INTO states (state, st) VALUES('RHODE ISLAND','RI');
INSERT INTO states (state, st) VALUES('SOUTH CAROLINA','SC');
INSERT INTO states (state, st) VALUES('SOUTH DAKOTA','SD');
INSERT INTO states (state, st) VALUES('TENNESSEE','TN');
INSERT INTO states (state, st) VALUES('TEXAS','TX');
INSERT INTO states (state, st) VALUES('UTAH','UT');
INSERT INTO states (state, st) VALUES('VERMONT','VT');
INSERT INTO states (state, st) VALUES('VIRGINIA','VA');
INSERT INTO states (state, st) VALUES('WASHINGTON','WA');
INSERT INTO states (state, st) VALUES('WEST VIRGINIA','WV');
INSERT INTO states (state, st) VALUES('WISCONSIN','WI');
INSERT INTO states (state, st) VALUES('WYOMING','WY');

--TERRITORIES
INSERT INTO states (state, st) VALUES('AMERICAN SAMOA','AS');
INSERT INTO states (state, st) VALUES('FEDERATED STATES OF MICRONESIA','FM');
INSERT INTO states (state, st) VALUES('GUAM','GU');
INSERT INTO states (state, st) VALUES('MARSHALL ISLANDS','MH');
INSERT INTO states (state, st) VALUES('NORTHERN MARIANA ISLANDS','MP');
INSERT INTO states (state, st) VALUES('PALAU','PW');
INSERT INTO states (state, st) VALUES('PUERTO RICO','PR');
INSERT INTO states (state, st) VALUES('VIRGIN ISLANDS','VI');

--CANADA


INSERT INTO states (state, st) VALUES('Alberta','AB');
INSERT INTO states (state, st) VALUES('British Columbia','BC');
INSERT INTO states (state, st) VALUES('Manitoba','MB');
INSERT INTO states (state, st) VALUES('New Brunswick','NB');
INSERT INTO states (state, st) VALUES('Newfoundland and Labrador','NL');
INSERT INTO states (state, st) VALUES('Northwest Territories','NT');
INSERT INTO states (state, st) VALUES('Nova Scotia','NS');
INSERT INTO states (state, st) VALUES('Nunavut','NU');
INSERT INTO states (state, st) VALUES('Ontario','ON');
INSERT INTO states (state, st) VALUES('Prince Edward Island','PE');
INSERT INTO states (state, st) VALUES('Quebec','QC');
INSERT INTO states (state, st) VALUES('Saskatchewan','SK');
INSERT INTO states (state, st) VALUES('Yukon','YT');

Sunday, May 25, 2008

ASP: Adding info to user profiles.

First: this is NOT a tutorial on adding security to your website. It's really about adding additional info to user profiles in ASP.net once you have created the profile.

It all started when I was asked to add some site-specific data to user profiles for a job. I wanted to add a license number (and some other fields) as part of our validation process.

Here is the short version for those who just want to make it work. All the examples here are in C# and ASP.NET 2008.

Quick Summary

First open your web.config file and find .

Right after that add a few lines. This example shows my own License Number field.

<profile>
  <properties>
    <add name="LicenseNo" type="System.String"></add>
  </properties>

Ok, that adds the spot for this data to the Profile object. Now here's what you do to access the data.

TextBox Example:

Make an ASP.Net AJAX web page in a secured directory. Then add this:

<asp:textbox id="tbLicense" runat="server"></asp:textbox>

Now click the Textbox and Select events from properties. Double click Init and create this handler (If you don't get the lightning bolt icon for events in the properties window, read this).

 protected void tbLicense_Init(object sender, EventArgs e)
 {
     tbLicense.Text = Profile.LicenseNo;
 }

Now add a handler for textchanged.

 protected void tbLicense_TextChanged(object sender, EventArgs e)
 {
     Profile.LicenseNo = tbLicense.Text;
 }

You could make the update happen on a button click if you like but I wanted immediate updates when the user changes the field. So go back one more time to the aspx page and on tbLicenseNo change AutoPostBack to True.

Now run your page.

DropDownList Example:

Here is an example with a dropdown list for account types.

in web.config

<add name="AccountType" type="System.string">

in the aspx page

<asp:dropdownlist id="AcctType" runat="server" autopostback="True" 
   oninit="AcctType_Init" onselectedindexchanged="AcctType_SelectedIndexChanged">
   <asp:listitem text="Customer" value="Customer"></asp:listitem>
   <asp:listitem text="Vendor" value="Vendor"></asp:listitem>
   <asp:listitem text="Investor" value="Investor"></asp:listitem>
   </asp:dropdownlist>

now the handlers

protected void AcctType_Init(object sender, EventArgs e)
  {
     string s = Profile.AccountType;
     AcctType.Items.IndexOf(AcctType.Items.FindByText(s));
  }
protected void AcctType_SelectedIndexChanged(object sender, EventArgs e)
  {
     Profile.AccountType = AcctType.SelectedValue;
  }

Done.

Detailed explanation:

What's happening? There is an object named Profile associated with every web hit. Note that I didn't have to create an instance of it or load it from anywhere. It's just there. Note what happens in the C# source when you type Profile. The context help pops up the names of the data items you added in the web.config file.

Now open up your aspnetdb.mdf database. The data are stored in the aspnet_Profile table. I do not recommend editing this data on your own through SQL. It's much easier to modify it via the asp.net profile object.

Monday, May 5, 2008

Graphics Question

This would be easy in Delphi, but I can't seem to get the objects I want to do what I need.

Ok, I have a function that creates and draws a maze on a Panel in a Winforms App. Then I sniped some code that manages to save the image of the panel to a bmp file.

WHY it's any harder than panel.canvas.savetofile is just stupid.

BUT!

If the panel is off the screen edge, or if it's obscured in any way, I get blank rectangle on the image (again stupid).

What I really want is what I've had for 10 years in Delphi.

I want to make my routine create the image in memory (even if the image is bigger than the screen). I want to be able to...

1. copy that image to the panel during a paint event

2. save the entire image to a file.

What I have run into so far is typical Microsoft.

First there are too may objects and no cohesive tutorial. I have tried the following objects.

  • Graphics. I can't create one linked to a memory bitmap.
  • Image. Nope you can't create one of these either.
  • PaintEventArgs you can create one but you can't use it.
  • Bitmap Nope I cnt get it to work.
What I want is this...
something MyPaintObject=new something(width, height, pixelformat);
MyPaintObject.clear(color);
MyPaintObject.fillrect(); 

...etc. Just regular paint commands

Then I want to be able to do this:

During a panel paint event: panel1.copyfrom(MyPaintObject);

...and when I want to save it, MyPaintObject.SaveToFile(filename, Bmp);

---

Ok, I got the answer: Here it is: thanks to a kind poster on the Microsoft forums.

Here's the Post: Graphics Question

Here's the answer.

Bitmap myBitmap = new Bitmap(200, 200, PixelFormat.Format24bppRgb);

public void DrawBitmap()

{

using (Graphics myGraphics = Graphics.FromImage(myBitmap))

{

myGraphics.Clear(Color.AliceBlue);

Pen Bic = new Pen(Color.Blue);

myGraphics.DrawEllipse(Bic, new Rectangle(0, 0, 199, 199));

}

}

private void panel2_Paint(object sender, PaintEventArgs e)

{

DrawBitmap();

e.Graphics.DrawImage(myBitmap, 0, 0);

}

Contact Us

Name

Email *

Message *