Pages

Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Friday, December 30, 2016

Making Transparent PNGs in C#

This bit of code shows how to make a PNG with transparency totally from scratch in code.  This code will save the image back as a file, but it could as easily be streamed back to a web request.  This is a complete console app, if you want to compile it, you'll need to add a reference to System.Drawing.



using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace TransparentPNGTests
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var bmp = new System.Drawing.Bitmap(100, 100, PixelFormat.Format32bppArgb))
            using (Graphics g = Graphics.FromImage(bmp))
            using (Font f = new Font("Univers", 14f, FontStyle.Regular, GraphicsUnit.Pixel))
            {
                //set up bitmap
                g.Clear(Color.Transparent);
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

                //draw text                
                Brush b = Brushes.Black;
                Rectangle textrect = new Rectangle(5, 5, 90, 90);  
                
                //using the rectangle instead of a point is a quick way to do word wrapping on the graphic
                g.DrawString("This is a bunch of text, for testing.", f, b, textrect);

                //save from the bitmap
                g.Flush(FlushIntention.Flush);   //this seems to be wise, but unnecessary.
                bmp.Save("bmpsave.png", ImageFormat.Png);                

                //save from the image - loses transparency
                //Image image = Image.FromHbitmap(bmp.GetHbitmap());
                //image.Save("image.png");
            }
        }
    }

}


Note that the last 2 lines:

Image image = Image.FromHbitmap(bmp.GetHbitmap());
image.Save("image.png");
Are the wrong way.   This is the way you'll find if you Google for "How do I save a Graphic object to a file or stream".  Somehow, the GetHbitmap function manages to mangle the formatting out of the image.
Here are the resulting images from this code.
Bitmap.Save()

Image Save()

Wednesday, December 2, 2015

How to Convert a Bitmap to an Image

I have seen a lot of crap about how to do this, and there is some very bad advice out there.
This:
Image img = (Image)myBitmap; DOES NOT WORK!

I did find a way to do this in one line of code. Many of the solutions I saw were 50+ lines of code, and most assumed you were saving the bitmap to a file first, which I did not want to do.

Image img = Image.FromHbitmap(bmp.GetHbitmap()); ...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Thursday, April 25, 2013

Min (n) must be less than or equal to max (-1) in a Range object.

This happened to me when I would read an XML file into a Dataset, as follows:

string sort = "";
string where = string.Format("userID={0}", EmployeeID);
DataSet ds = new DataSet();
ds.ReadXml(XMLFilename);
DataRow[] rows = ds.Tables[0].Select(where, sort, DataViewRowState.CurrentRows);

The userID column is numeric, yet I found that I could make this error dissappear by single-quoting the parameter like this.

string where = string.Format("userID='{0}'", EmployeeID);

...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Tuesday, February 12, 2013

DropdownList: SelectedValue does nothing.

 I have a ComboBox set as a DropDownList, and the SelectedValue property, which ostensibly will find and select the selected value, does not.

cbSalesman.SelectedValue = salesman;  This is probably because you would need to give it not just a string to look for, but an actual object that is a member of the Items list.  That would require ugly gyrations along the lines of the following.
  1. get the string to look for
  2. get the index of that string in the dropdown (using Items.IndexOf)
  3. grab the item at that index
  4. feed it to the "SelectedValue" property.
Instead of all that, why not just do this.

cbSalesman.SelectedIndex = cbSalesman.Items.IndexOf(salesman);


...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Tuesday, December 4, 2012

Operation is not valid due to the current state of the object.

App Details:

Visual Studio 2010
Desktop Winforms App
MDI Child form with a Datagridview connected to SQL Server 2008

Error details:
When closing the form, debugger jumps to this line in form.designer.cs (one of the files you are not supposed to edit).

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
    if (disposing && (components != null))
    {
        components.Dispose();  //<<<---error points here
    }
    base.Dispose(disposing);
}
and here is the massive error...

System.InvalidOperationException was unhandled
  Message=Operation is not valid due to the current state of the object.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.DataGridViewCell.GetInheritedStyle(DataGridViewCellStyle inheritedCellStyle, Int32 rowIndex, Boolean includeColors)
       at System.Windows.Forms.DataGridViewCell.GetPreferredWidth(Int32 rowIndex, Int32 height)
       at System.Windows.Forms.DataGridViewColumn.GetPreferredWidth(DataGridViewAutoSizeColumnMode autoSizeColumnMode, Boolean fixedHeight)
       at System.Windows.Forms.DataGridView.AutoResizeColumnInternal(Int32 columnIndex, DataGridViewAutoSizeColumnCriteriaInternal autoSizeColumnCriteriaInternal, Boolean fixedHeight)
       at System.Windows.Forms.DataGridView.OnColumnGlobalAutoSize(Int32 columnIndex)
       at System.Windows.Forms.DataGridView.OnColumnCommonChange(Int32 columnIndex)
       at System.Windows.Forms.DataGridViewCell.OnCommonChange()
       at System.Windows.Forms.DataGridViewComboBoxCell.set_DataSource(Object value)
       at System.Windows.Forms.DataGridViewComboBoxCell.DataSource_Disposed(Object sender, EventArgs e)
       at System.EventHandler.Invoke(Object sender, EventArgs e)
       at System.ComponentModel.Component.Dispose(Boolean disposing)
       at System.Windows.Forms.BindingSource.Dispose(Boolean disposing)
       at System.ComponentModel.Component.Dispose()
       at System.ComponentModel.Container.Dispose(Boolean disposing)
       at System.ComponentModel.Container.Dispose()
       at Onesource.MaterialReceiptsEntry.Dispose(Boolean disposing) in P:\Projects\myproject\sample\MaterialReceiptsEntry.Designer.cs:line 18
       at System.Windows.Forms.Form.WmClose(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DefMDIChildProc(IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at System.Windows.Forms.Form.DefWndProc(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WmSysCommand(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DefMDIChildProc(IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at System.Windows.Forms.Form.DefWndProc(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.ContainerControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WmNcButtonDown(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Onesource.Program.Main() in P:\Projects\myproject\sample\Program.cs:line 19
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:
The solution:
I was looking through the ugly error stack above and found a lot of references to stuff like GetPreferredWidth. Having previously dealt with numerous problems involving AutoSizeColumnsMode and DataGridViewComboboxColumns,   I decided to try testing the form with AutoSizeColumnsMode set to None.  The layout did suck, but the form stopped crashing...

This means that the datagridview is trying to resize its columns during a form close!  Here is what I did to solve the problem.

I set the AutoSizeColumnsMode to AllCells and added a FormClose event as follows...




private void MaterialReceiptsEntry_FormClosing(object sender, FormClosingEventArgs e)

{

myDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;

}

This ensures that the grid will not be updating its column sizes as the form is closing.



...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Thursday, November 29, 2012

Case Schizophrenia and the DataGridViewComboboxColumn

So by default SQL Server (Microsoft) creates indices* and  does searches that are case insensitive.

Select * from orders where salesrep='bob' Will find BOB, bob, bOb, etc. (but not Robert)

So I have a DataGridViewComboboxColumn for that field, but since the data all comes from Paradox, where anything goes, I have a mixture of case scenarios.

As it turns out, even though your database cares not what capitalization you use, the combobox does.  It WILL NOT MATCH a field that has an alternate capitalization of whats in your data.

Example: if you have DONNA in the lookup list, and Donna in the orders table, the dropdown will display SOME RANDOM OTHER NAME.

It also throws a dataerror that looks like...

Order Entry [OrdersGrid]: Row 2 Column 16 Context Formatting, PreferredSize... System.Windows.Forms.DataGridViewDataErrorEventArgs DATA: TONYA 

...and it throws this error for each and every row you attempt to display on the screen.

The solution?

All I did was load the Purchase Orders table using the salesman as its own lookup.  like this

update Purchase_Order set Salesman=(select Salesman from Salesman S where S.Salesman=Purchase_Order.Salesman)

So, we're looking up the salesman, say "Bob" in the Salesman lookup table (finding, say "BOB") and writing that back over the Bob in the row, essentially updating the names in such a way as to match exactly what's in the lookup table.

Now our DataGridViewComboboxColumns work, and we didn't even have to edit the program!




...
* I still can't make myself use the word indexes.

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Sunday, September 23, 2012

Getting the Identity Of Inserted Row in Visual C#

This works to return the identity of an inserted row.  The highlighted portions are the important parts.

 private int insertnew()
        {
            int newtix = 0;
            string SQL1 = "insert into delivery (date) values (GETDATE()); SELECT CAST(scope_identity() AS int)";
            SqlCommand myCommand = new SqlCommand(SQL1, myConnection);

            try
            {
                newtix = Convert.ToInt32(myCommand.ExecuteScalar());
            }
            finally
            {
                myReader.Close();
            }

            return newtix;
        }
Note that
  1. there are 2 SQL commands in the one SQL string.
  2. I had to cast the Scope_Identity as an int in the SQL or it would not read.
  3. ExecuteScalar reads the FIRST column in the FIRST row only, but if there were a compound key, or multiple rows inserted, ExecuteReader can be used instead.



Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Wednesday, August 29, 2012

Sucky Docking in Visual Studio

Delphi always did this right.  Even back in 1990.  But Some dipshit at Microsoft thought this would be the perfect way to make controls dock.  When you dock a binding navigator to the top of your panel or form, and then a Datagridview to "fill", Microsoft thought this is what you'd have in mind.


 Even the little box that pops up seems to show it correctly.

Whatever the case, I must now use a splitter - an object with tons of functionality that I don't want - to complete my layout.

Microsoft, you SUCK.

...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Wednesday, August 1, 2012

C#: Quickly Strip out all the Spaces from a String

This line of code will remove all spaces from a string.

string s="Some string with spaces";
string s2 = string.Join("",s.Split(' '));

...

Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Friday, March 16, 2012

C#.NET Finding the First Day of the Week in One Line of Code

while (myDate.DayOfWeek != DayOfWeek.Sunday) { myDate = myDate.AddDays(-1); }


Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Thursday, February 16, 2012

Open a Web Page from C#.NET

How to easily open a web page from your C# App.

System.Diagnostics.Process.Start("http://209software.com/");



Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Tuesday, September 7, 2010

Easy XML Dataset Tutorial in Visual C# Express

Create the Data Definition
First, create a new application.
 Add a dataset
Right-click in the stripes and add a datatable.
Right click the datatable to add all the columns you want.
Use the Properties form to set column properties.
Repeat until your table is complete.

Continue this until your dataset is complete.  You can add as may tables as you like.  Keep in mind that you are not creating a database (as you would in SQL Server), you're creating a data definition or schema.

Ok, now to use the dataset in your program.
Set up for Editing
From the top menu, select data - show data sources.
Now, just drag a table from the list to your form.
Notice that a number of components are added to your form when you do this...

Now it's time to hook up the UI to a dataset.  First, enable the save icon in the toolbar.

Next, construct the file/save routine.



Now it's time to tell the dataset how to load the data on startup.  Select the dataset and add an Initialized handler.
The trick here is to make sure the xml file exists before loading it.








Now run the program, and enter data.
 Click the SAVE icon, and exit the program.  Then launch it again to verify that the data has been saved.  Simple, eh?
But, where is my XML file?
Since you ran the application in debug mode, your xml data file was created in that directory.  From the C# IDE menu, select File - Open File... and select bin, then debug.  Your xml file is there, and should look a lot like this:

If you want to know more, like how to read/write data to this kind of dataset in code - just leave me a comment!


Bryan Valencia is a contributing editor and founder of Visual Studio Journey.  He owns and operates Software Services, a web design and hosting company in Manteca, California.

Monday, August 23, 2010

ASP.NET User Profiles.

It totally sucks.
Membership data in the ASP.NET database stores user names, emails, and a little other information, but I need to add more... All I want is a few additional columns added to the user's data, like their real name, phone/fax/cell numbers, etc. I don't want to go to the trouble of creating a SQL Server table and managing all the relationships to do this and then creating the SQL to fish that all up in my code.
Well, as it turns out that's exactly what the ProfileCommon object does.
There are a number of uncommonly pleasant surprises when you dig into this feature, so let's get started!
This article assumes you're using an aspnet default database setup created as in this article.
Ok try this: In your code pages, type Profile.: you will see a hint showing the options available.
Profile Context Help
yes you can stretch the pop-up box!
Now, open your web.config file. Look for the end of the system.web section. Insert the following lines.
<profile defaultProvider="ProfileProvider">
            <providers>
                <clear/>
                <add connectionStringName="ConnectionString" applicationName="/" name="ProfileProvider" type="System.Web.Profile.SqlProfileProvider"/>
            </providers>
            <properties>
                <add name="email_verified" allowAnonymous="false" type="System.Boolean"/>
                <add name="subscribed" allowAnonymous="false" type="System.Boolean"/>
                <add name="MemberID" allowAnonymous="false" type="System.String"/>
                <add name="FullName" allowAnonymous="false" type="System.String"/>
            </properties>
        </profile>
OK, obviously your connection string has to be changed to match the one in your Membership and Roles provider. Look at the profile section. The editor doesn't help much with creating these types, but they are not hard to figure out.
All you need to do is create whatever columns you want to add. Then once they are added here, go back to your C# code and type Profile. again.

Notice that the added properties are now available to you to use in your programming. You can display then onscreen, let people edit them, even modify them in your code.


The Profile object is of type ProfileCommon, and is automatically instantiated when your page is loaded. Here are a few shortcuts for using it.


Use the logged-in user's Profile Profile.[fieldname]
Look up another user's Profile ProfileCommon otherProfile = Profile.GetProfile(otherUSerName);

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, 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 *