Pages

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);

}

Wednesday, April 30, 2008

Using Subversion with Visual Web Developer

*Note: this method doesn't just work for Visual Web Developer, it should work for any software where source files are stored on your local drives. This includes C#, C++, Java, VB, Delphi, C++ Builder, Flash, Poser, etc.

This tutorial will get you started using Tortoise SVN to easily back up and version your websites. If you don't know why this is a great idea, then you've never screwed up your projects so bad that you wasted 3 days trying to get it back to where you started.

Step 1

Find a spot to back up your stuff. I use an external USB drive. There are also ways to do this over the intranet and Internet. You can store your archive (subversion calls this a repository) on your main hard drive, or another computer in your network as well.

Step 2

Download and install Tortoise SVN for windows. Once installed, right-click nearly any file on your system and note the new options that are available (Don't select them yet, just *note* them).

Step 3

Create a folder on your archive drive to put a project in. In my case, on the external drive it's named like this: I:\subversion\Website1.

Then navigate to the parent folder and right-click the project archive folder (in my case this was I:\subversion) and right-click the new archive folder (Website1). Choose TortoiseSVN - Create Repository Here. Select Native Filesystem (FSFS). This takes a few 10ths of a second, and creates files and folders in the archive folder.

Step 4

Now browse back to your websites folder (the place where you have the files to be archived) and right-click the project you want to check in. Select TortoiseSVN - Import. It is important to note that to Tortoise, import means "import to the archive" and export means "Pull it out of the archive". In the import dialog select the archive folder you just created (such as file:///I:/Subversion/Website1. Click OK. The contents of your project will be imported into the repository. Click OK.

Now whenever you change a file in your project, you can upload the changes to the repository, and if you mess it up, you can roll it back in an instant! I'll do more tutorials about using Tortoise SVN later.


Apologies for the delay...

Yes, you must use tortoise to check out the project again. I suggest checking it out to a new folder. There are some Windows sharing settings that will cause errors here if you are saving to a shared drive. I am still looking into this.

Saturday, April 26, 2008

Error: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

When accessing a SQL Database from an ASP.NET page, I sometimes get this error:

Error: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

... This seems to be because the SQL Server isn't spun up all the time like Oracle is. So initially after a long pause it seems to take a lot longer to set up again.

There are 2 possibilities here, one is that you are timing out before a connection is made, and the other is that your command is taking too long to execute.

Connect Timeout Set the Connect Timeout to a much higher value, like 120.

ComandTimeout Set the CommandTimeout to a much higher value.

Tuesday, April 15, 2008

MSSQL Update Trigger Example

This tutorial shows how you would create a trigger in Microsoft SQL Server 2005/2008 that will date/timestamp a column named last_updated everytime any data in the row is updated.

This example assumes a primary key that includes 3 fields.

CREATE TRIGGER MyTableUpdate
ON dbo.MyTable
FOR update
AS
UPDATE
MyTable
SET last_updated = GetDate()
From MyTable Inner Join Inserted On
MyTable.KeyField1 = Inserted.KeyField1
and MyTable.KeyField2 = Inserted.KeyField2
and MyTable.KeyField3 = Inserted.KeyField3

Thursday, March 20, 2008

Missing Event Handlers

First, has anyone other than me noticed that it takes like 2+ minutes for Visual Web Developer to fully open and come alive? What the hell is it doing? We'll save that for another time.

So you create an Ajax Web Form. You want to put an even handler on Init of the form. How? There is no event icon in the object inspector for the document.

So you click on the Script manager and presto! you get the little lightning bolt icon.

Let's try it with a master page. We create a master and a content page and guess what? There is NO WAY to add an onInit handler to the content page. There's no script manager. If you open the .cs code file and/or double-click the page in the designer, you get a page_load function.

You can try to add one by hand, but where would you put that?....

Ok lets move on.

Slap a button on the screen, and then select the button. Wohoo! the little lightning bolt is there!

Now create a table and put in a row and a cell and put the button in there. Oops, you can no longer click the button and create event handlers, you keep getting the table. In fact the only way I have found to add a handler is to drag the button out of all the panels, tables, etc., and edit it's event handlers, then drag it back into it's table cell and hope it all works.

This is goofy.

The solution is to create all components you need to access the events of outside all tables tables or panels, create the event handlers and then drag (or cut/paste) the objects back into the table or panel.

Tuesday, March 11, 2008

IE7 Displays Blank Page: Firefox OK.

When I try to browse to my website, which contins an ASP page, I get a blank page for IE7, yet all is well for Firefox.

View Source in Firefox gives the normal page, while IE just shows this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; 
charset=windows-1252"></HEAD>
<BODY></BODY></HTML>

The page had some Flash embedded, but I get this result even after removing it. Im heading for "Clearly, IE is BROKEN". What MORON would have a browser substitute a blank page without any kind of error or warning message?


I found the solution after pulling an all-nighter on it.

This had to do with a database error: here's what happened. For some reason the database error was NOT getting reported to the browser, it just got a blank page.

I store the data from every hit in a table for diagnosing problems. That data element was a varchar(250), which up until now was more than adequate. The string from a firefox hit comes in at 163 and looks like this:

03/10/2008 16:24:14 Mozilla Netscape 5.0 (Windows; en-US) Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12 en-US Win32

However IE7 sends this for the exact same page:

03/10/2008 16:24:14 Mozilla Microsoft Internet Explorer 4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.590; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022) Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.590; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022) undefined Win32

That's a whopping 380 characters, which caused a string length error on my SQL insert command.

I still don't understand why in hell it returned a completely blank page to IE without any errors listed but whatever, I'm re-doing the whole site in ASP.NET anyways.

The ANSWER: I had to stretch the database column where I'm storing the hit data strings to 1000 characters. That ought to hold me until IE8 SP2 at least.

Thursday, March 6, 2008

ASP.NET: Uploading Files

This is so easy. Drop a FileUpload object onto your AJAX web page. Drop in a button.

In the button event handler, do this:

//get the path to the UPLOADS directory in your webbserver
        string path=Server.MapPath(@"~\Uploads"); 

//create the full path+file name
        string SaveAsName=path+@"\"+FileUpload1.FileName;

        try
        {

//This is the bulk of it right here.
            FileUpload1.SaveAs(SaveAsName);
        }
        catch(Exception err)
        {
            Label1.Text = err.Message;
        }

That's it. The FileUpload object hands you all the data and functionality you need. Of course I could have checked to see that the file being uploaded is of a certain size or type, but this quick tutorial is just about the basics.

Sunday, February 17, 2008

Permissions...

This article is about setting up private, member-only areas of your website that are either for admins or clients to access. The .net framework gives several easy ways to set this up with a minimal amount of coding.

Assuming you already have a website, and wat to add a restricted zone, do this:

First, enable permissions for your website

WebSite->ASP.NET Configuration
Browse to the security tab.

There are essentially 3 things to configure: Users, Roles, and Access. By default this data is stored in a MSSQL database in your website's folder structure.

I like to enable roles first, creating roles like client, admin, mod, or whatever. This process is easy enough. For this tutorial, create a user, and give it the admin role. Now before we can add access, we'll close the config screen and return to our project.

Create a folder



Add any html or aspx web page to the new folder. Add a link to the new page to your main website.

If you run the website now, you get free access to the new page (we haven't limited access yet).

Return to the ASP.NET Configuration and on the security tab, click Manage Access Rules.

Click on the new admin directory and then add allow permission for admin role. Then add deny permission for all.

The way this works is that this list is accessed from top to bottom, looking for a permission to apply. The first match that is found is applied. Therefore if we gave the deny - all permission first, then nobody would have any access to the folder.

The Login Page

By default, the login page is named login.aspx. This page will load any time that the client doesn't have sufficient privileges to access the page asked for. It must be in the unprotected part of your website.

So create a new page named login.aspx. Add in a login and password recovery gizmo from the login tab of the toolbox. Click on the gizmos and use the Auto Format function from the pop-out box to select the perfect style.

That's it.

Now anytime the user tries to access a page that he's not logged in for, he first gets the login screen. If he is already logged in, he gets the screen he asked for without interruption.

It's cool. I know.

Saturday, February 9, 2008

ASP.NET How to open a URL in a pop-up window.

Note: if you just want the browser to open a page in another browser page, look up the target parameter of the a href tag.

If you just want to pop a quick message box, look up the javascript alert function.

This article demonstrates how to pop up a new browser window on the click of a hyperlink and load whatever page you want in a controlled browser window.

In the head portion of your page , put the following javascript function.


<script language="javascript">function Pop(URL){
  a=window.open(URL,'MyWindow','status=0,toolbar=0,width=300,height=250');
  a.focus();
  return false;} 
</script>

AJAX NOTE:this can be in the AJAX master page, or in the "Content1" head section of the content page, as I show here.)

Then create a link in the body of your article, like this:


<a onclick="return Pop('htmlpage.htm')" href="http://www.blogger.com/">Test the popup feature</a>

Here's the details of how this all works.

URL: Within the function: We pass in the URL to open from our call to the function. The URL can be any html, shtml, or aspx page.

window.open: Call this javascript function and give it a URL, a window name (the html name of the document) and the opening parameters. You can use the name parameter to control the number of popups. For instance, if we created 10 links all naming the same name (like "MyWindow"), then they will all load in the same pop-up window. If we create 10 links all naming different windows, then each hyperlink will sen the page to it's own named window.

Using the parameters in my example, the pop-up window will be a fixed size, and have no status bar or toolbars. Here is a more complete list of parameters:

status The status bar at the bottom of the window.
toolbar The standard browser toolbar, with buttons such as Back and Forward.
location The Location entry field where you enter the URL.
menubar The menu bar of the window
directories The standard browser directory buttons, such as What's New and What's Cool
resizable Allow/Disallow the user to resize the window.
scrollbars Enable the scrollbars if the document is bigger than the window
height Specifies the height of the window in pixels. (example: height='350')
width Specifies the width of the window in pixels.

a: Once Javascript creates the window, it assigns it to the Javascript object (in the example it's named "a").

a.focus(): If the user clicks the link on the main page again after the window was initially created, the main page may cover the pop up. This line says that whenever we pop or reload this window's URL, we'll set focus on it.

return false: It's a function. We're returning false. Bear with me, I'll explain why in a moment.

Now we'll look at the hyperlink. It's a nearly standard html construct with a few unfamiliar twists.

href="": This says to browse to noplace. We could have left this out, but then the link would not look like a link in the page. It would look like regular text. Normally passing in "" as the href would force a reload of the page we're already on, I'll show how to stop the page from reloading later.

onclick=: This is where we tell the link nto call our function. Now we could have just said onclick = "Pop('hrmlpage.htm')" but as it turns out the onclick event expects a return value. If that value is true, then the link exectues its default behavior and browses to the link in the href parameter, but if it recevices a false, it skips that part. We could have done this:


<a onclick="Pop('htmlpage.htm'); return false;" href="">Test the popup feature</a>

...and the reload of the main page would be suppressed. But in our case, since our function already returns a false (handy, huh?), we can use that value to tell onclick to stop the link from reloading. We need to tell the onclick call to accept the value of the function with the return keyword as shown in the original version of the html link.

Note that there is no reason the Pop function must be married to a hyperlink. It is possible (though annoying) to call it on page load, mouseover events, or any other browser event.

Monday, January 21, 2008

Why is EVERYTHING so Damned Hard?

Windows 2003 SBS ASP.NET 2008 Express SQL Server 2005 .net framework 3.5 (not beta)

So, I wanted to add a login page to my website and offer more content to logged-in users. I saw the login components and followed the tutorial to the letter. It works on my desktop perfectly. I can create logins and even the forgot my password crap works. I publish it to my website, and try to log in.

An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections.

Oh, shit! So I search the help (when am I going to learn?) and it tells me that all I have to do is open an Application that DOES NOT EXIST on my server, and grant THE INTERNET access to my DATABASE. I don't think so.

Please, if you know what is wrong, go to http://209software.com/Login.aspx and use the username "a" and the password "a". It's not a valid login, but it crashes every time trying to verify.

My web server, email server, and database server are all the same machine.

Here's what I want to know, and MSDN has squat on it.

  1. if I grant database access to the database, can people BROWSE my database over the web?
  2. What am I doing wrong? and how do I make it right?
  3. WHERE on the internet can you go if the Microsoft help is crap?

Ok, I got it. I downloaded something, but it wasn't SQL server 2005 express. Now, a mere 8 hours of downloading and installing later, it seems to work.

Monday, December 10, 2007

Wednesday, November 21, 2007

Creating a new Class

Create a new winforms project, then right-click the project and do this:

Create a new Class object

Add this code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassDemo
{
    class newClass
    {
        public string sharedString = "This can be read and written by anyone.";
        private string myString = "Only visible in newClass.";


    }
}

And then right-click and add a 'ctor' (constructor) snippet as shown.

Tuesday, November 20, 2007

Day 5: Arrays

The website of the day is here.

And here is the example code...


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace Arrays
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            /*
             * Arrays Demo
             */
            richTextBox1.AppendText("FIXED ARRAYS"+Environment.NewLine);
            //a fixed array of 4 strings (0-3), initialized on create.
            String[] myfamily = new String[]
               {"Bryan", "Ruth", "Rebekah", "Rachel"};
            
            //a fixed array initialized later
            String[] myPets = new String[3];
            myPets[0] = "Sasha";
            myPets[1] = "Ross";
            myPets[2] = "Nightstar";
            
            //reading fixed arrays
            foreach (string s in myfamily) 
            {
                richTextBox1.AppendText(s + Environment.NewLine);
            }
            foreach (string s in myPets)
            {
                richTextBox1.AppendText(s + Environment.NewLine);
            }

            Random R = new Random();
            

            int P = (int)R.Next(3);
            int F = (int)R.Next(4);

            string playtime = 
              string.Format("{0} is playing with {1}", myPets[P], myfamily[F]);
            richTextBox1.AppendText(playtime + Environment.NewLine);

            //variable Arrays
            richTextBox1.AppendText(Environment.NewLine + 
              "VARIABLE ARRAYS" + 
              Environment.NewLine);
            //untyped array
            ArrayList RandomStuff = new ArrayList();
            //you can put anything into this array            
            RandomStuff.Add(new Font("Arial",12));
            RandomStuff.Add(7.1);
            RandomStuff.Add("The Castle Anthrax");

            //now... how can we work with this collection of trash?

            foreach (object O in RandomStuff)
            {
                richTextBox1.AppendText("I see a(n) " + 
                  O.GetType()+Environment.NewLine);
                if (O is System.Drawing.Font)
                    richTextBox1.AppendText("   ->" + 
                      (Font).FontFamily+Environment.NewLine);
                if (O is Double)
                    richTextBox1.AppendText("   ->" + O.ToString() +  
                      Environment.NewLine);
                if (O is String)
                    richTextBox1.AppendText("   ->" + O.ToString() + 
                      Environment.NewLine);                    
            }

            //typed vararrays
            richTextBox1.AppendText(Environment.NewLine + 
             "TYPED VARIABLE ARRAYS" + 
             Environment.NewLine);
            List<String> myStrings = new List<String>();
            List<Double> myNumbers = new List<Double>();
            List<Button> myButtons = new List<Button>();


            myStrings.Add("Bread");
            myStrings.Add("Mayo"); 
            myStrings.Add("Turkey");
            myStrings.Add("Cheese.Provolone");
            myStrings.Add("Bread");

            foreach (string ingredient in myStrings)
            {
                richTextBox1.AppendText(ingredient + " ");
            }
            richTextBox1.AppendText(Environment.NewLine);

            /*
             * Since these arrays are stongly typed, you can't put a 
             * string into the button array nor a number into the 
             * string array.  you *can* however put the descendant
             * of a any object into a typed array.
             */
        }
    }
}



Todays Assignment: make a list of your favorite things.

Monday, November 19, 2007

Day 4: launch an outside App

This is a little less formal than previous posts, but here goes. First, create a form with a button, a RichText, and a PictureBox.

Here is the source code I wrote to accomplish this. I am a big believer in examples. They tell the story in a far more eloquent way than my witty expose'.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Diagnostics;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        Process POVRay = new Process();
        

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            StringBuilder povtext = new StringBuilder();
            string camera = "camera{location <0,1,-1>*10 look_at<0,0,0>}";
            string light1 = "light_source{<0,1,0>*1000 color rgb 1}";
            string water = "plane{y,0 texture{pigment{color rgb 0.5}"+
                " finish{reflection .2 }" +
                " normal{ bumps .4 turbulence .7 }}}";
            string sphere = "sphere{<0,1,0>,1 pigment{color rgb<1,0,0>}}";

            povtext.AppendLine(camera);
            povtext.AppendLine(light1);
            povtext.AppendLine(water);
            povtext.AppendLine(sphere);

            richTextBox1.Text = povtext.ToString();

            //save to file

            using (StreamWriter sw = new StreamWriter("C:\\temp\\demo.pov"))
            {
                // Add some text to the file.                
                sw.WriteLine(povtext);
                sw.Flush();
                sw.Close();
            }


            //launch POV-RAY and create a new bitmap;
            Process POVRay = new Process();
            POVRay.StartInfo.FileName = 
                "C:\\Program Files\\POV3.6\\bin\\pvengine.exe";
            POVRay.StartInfo.Arguments = 
                "+IC:\\temp\\demo.pov +OC:\\temp\\demo.bmp +w320 +h200 -P -D /EXIT";
            POVRay.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;           

            POVRay.Start();
            POVRay.WaitForExit();
            this.pictureBox1.Load("file:C:\\temp\\demo.bmp");
           
        }
    }
}


You will need POVRay to run this.

Your assignment: figure out how to launch another application like Word, Firefox, or Notepad.

Enjoy.

Thursday, November 15, 2007

Day 3: WinForms App

Less prose! More examples!

Start C# File - New Project.

Windows Forms Application.

This is what you should see.

Look in the toolbox for a class object called a button and another called a textbox. Do something like this:

Rightclick the textbox. Select properties.

Look now at the properties box.

Ok now a few things to note. Look at the speed buttons just below the word "textbox1". The first 2 icons pick whether you are sorting alphabetically or by groups. The next 2 icons determine whether you are viewing properties or methods.

Now find the multiline property of textbox1 and change it to true.

Note how the handles on the textbox have changed. Grab the lower right handle and stretch it like this.

ok, now double click button1 in the editor.


        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = "Written by CODE";
        }

Add the text in bold. Then hit the F5 key to start with debugging. After clicking the button, you'll see this.

More examples...

        private void button1_Click(object sender, EventArgs e)
        {
            //this is a comment, the compiler ignores it.
            /*
             * this kind of comment can span more
             * than one line
             */

            //putting text in the textbox
            textBox1.Text = "Written by CODE";

            //adding to the text that is already there.
            textBox1.Text += " because we cared.";
            
            //newline example 
            /*(Environment.NewLine ensures that 
             * the correct chars are used based 
             * on the operating environment)*/
            textBox1.Text += Environment.NewLine+"(new line)"; 

            //appendtext
            textBox1.AppendText(Environment.NewLine);
            textBox1.AppendText("appended text");

            //casting non-strings
            textBox1.AppendText(Environment.NewLine);
            double j = 22.0 / 7.0;
            textBox1.AppendText(j.ToString("F04"));

            textBox1.AppendText(Environment.NewLine);
            int i = 1024;
            textBox1.AppendText(i.ToString());

            //results of methods
            textBox1.AppendText(Environment.NewLine);
            textBox1.AppendText(Environment.CommandLine);

            //math results
            textBox1.AppendText(Environment.NewLine);
            textBox1.AppendText(Math.Cos(0.1).ToString("F05"));

            textBox1.AppendText(Environment.NewLine);
            textBox1.AppendText((110.0/73.0).ToString("F05"));

            //dates
            textBox1.AppendText(Environment.NewLine);
            DateTime D = new DateTime(2007, 12, 31, 17, 00, 00);
            textBox1.AppendText(D.ToShortDateString());
            textBox1.AppendText(" "+D.ToShortTimeString());

            DateTime NOW = DateTime.Now;
            TimeSpan diff = D - NOW;
            textBox1.AppendText(Environment.NewLine);
            textBox1.AppendText(diff.Days.ToString()+" days " );
            textBox1.AppendText(diff.Hours.ToString() + " hours");
            textBox1.AppendText(diff.Minutes.ToString() + " minutes");

            //changing object properties
            this.BackColor = Color.AliceBlue;
            this.ForeColor = Color.Blue;

            /*
             * note how we can refer to the current form as "this"
             * 
             */
        }

Tuesday, November 13, 2007

Day 2

housekeeping

Here are the books and websites I use most when the answers are not coming to me.

C# for Programmers (2nd Edition) (Deitel Developer Series)

Pop open Microsoft Visual C# 2008 Express Edition - I suggest you pin it to your start menu.

Notice the area in the center, called the Start Page.

Now look closer at the "Getting Started" section.

There are actually some good resources there for you to use.

ready, set, go.

Today we create our first application.

Sadly it'll be a console app.

Click File - New Project - Console Application. You'll get something that looks like this:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  class Program
  {
      static void Main(string[] args)
      {
      }
  }
}

The using's are all the .net namespaces or libraries that are included in the project by default.

The ConsoleApplication1 namespace is your own private realm where your code exists. All .net code exists in a namespace.

Variables

As I mentioned, all things in C# are class objects. The difference between a class object and a variable are that class objects can contain methods and they can be extended. An int in Delphi can't have any of its own functions, but in C#, even the simplest data object can and does.

Do this: Add this to the code above.

      static void Main(string[] args)
      {
          int x;
          int y = 2;
          x = 7;
          int z = x + y;          
      }
  }

int x; creates an integer class object but does not assign it a default value. Any attempt to read or manipulate it at this point would cause an exception.

The int y = 2; line shows a shorthand way of creating and initializing the value at the same time.

The x = 7; shows how to add or change data in an existing data object.

The int z = x + y; line shows a variable z being created containing the results of a calculation. Note that subsequent changes to x and y will not cause z to recalculate, it just works the math at the time and stores it in z.

Now do this. Type z. and a popup context helper appears. This shows the methods that can be accessed from an int.

if you mouse-hover over the items you get an explanation like this.

Ok, time to move on to...

EMail Demo

Now clear out all the varibables and type in the word MailMessage as shown.

Note the little rectangle under the "e". Hover your mouse over that and you'll see this:

What the IDE is offering to do is add the namespace System.Net.Mail to your using section or, alternately, add it to the declaration itself. You don't have to add a namespace to your project to access it, you can explicitly pick objects from any namespace by using their fully qualified name. Adding them to the using clause just simplifies the typing.

In this case, choose the first one, add System.Net.Mail to the using section.

Now you'll see the using System.Net.Mail; has been added to the top section of the program and all the objects and methods in that namespace are now native to your program.

The MailMessage class is an object that can be used to send or receive email messages. You can create an empty one and load it later like this...


MailMessage myMailMessage = new MailMessage();
myMailMessage.To = new MailAddress("bryanv@eloan.com", "Bryan Valencia");
myMailMessage.From = new MailAddress("gumby@eloan.com", "Gumby and Pokey");
myMailMessage.Subject = "I am feeling down again.";
myMailMessage.Body = "I am all congested with disclosures.";

Or you can create it and initialize it with variables. Note that we had to create 2 MailAddress objects to set the To and From addresses in myMailMessage.

The following example shows how to create a MailMessage object with all its values pre-initialized.


      static void Main(string[] args)
      {
          MailMessage myMailMessage = new MailMessage(
              "gumby@eloan.com",
              "bryanv@eloan.com",
              "I am feeling down again.",
              "I am all congested with disclosures."
          );
      }


Ok, now let's send this bad-boy. In order to do that (and please feel free to substitute your own address for the To address), you need an object called the SMTPClient. It's in the same namespace as the MailMessage.


      static void Main(string[] args)
      {
          MailMessage myMailMessage = new MailMessage(
              "gumby@eloan.com",
              "bryanv@eloan.com",
              "I am feeling down again.",
              "I am all congested with disclosures."
          );

          SmtpClient mySMPTClient = new SmtpClient("eloan.com");
          mySMPTClient.Send(myMailMessage);

          Console.WriteLine("Message Sent");
      }

Now, hit Control-F5, or from the menu, Debug - Start without debugging. You should get this:

Then in about 10 seconds, whoever you decided to bless with your email should see it in their inbox.

Let me diagram what we just did. When we created the MailMessage object, here's what was happening:

what we typedwhat happened
MailMessageWe told C# that we are about to create an object of the class MailMessage in the System.Net.Mail namespace.
myMailMessagewe told C# that we are going to call it myMailMessage.
= new MailMessage(...)We told C# to go ahead and create it now - that means to allocate memory and initialize it with either default values or the ones we are passing in. The object is now created and resides somewhere in memory, and can be accessed by the name myMailMessage.

Constructors

Every class object has a predefined method called a constructor. It tells C# how to create instances of itself. Constructors can be simple, like the constructor for an int, or more complicated like the one for MailMessage. They can even be overloaded.

Try this:

Note how the context helper pops up a helper for the constructor. There are 4 overloaded constructors for the MailMessage class. Use the down arrow key to see the formats you can choose from. All methods in all objects will pop these helpers while you are editing.

A few little items

Single quotes and double quotes are not interchangeable. Strings use the double quote marks "like this". Chars use the single quote (or tickmark or apostrophe), like this: 'A'.

A class is the organization of an object, an object is an instance of that class. Or, think of classes as cookie cutters (or blueprints) and objects as cookies (or Lear Jets).

Overloading means that there can be many methods with the same name. More on this later.

Share This!

Contact Us

Name

Email *

Message *