Posts Tagged .NET

Northwind Database For Oracle

Ah Northwind. The database everybody learns on. Well almost everyone. I realize it is a Microsoft product but you would have thought somebody along the line would have developed the same for Oracle and MySQL.

Why did this come up? In the next rendition of MySQLMove (which is being renamed for the next release – I still haven’t settled on a title for it yet. Something that indicates it is multi environment data collector and reporter. If you have suggestions or ideas please let me know…) I have been telling you about I wanted to add Oracle back ends as an option to get your data from. During the examples on past releases I used Northwind to demonstrate how to use the software. So I looked high and low on the web and didn’t find a single useable version of Northwind for Oracle. So I did it the old fashioned way. I exported my Northwind from SQL, table by table to excel files and imported them into Oracle. There’s an hour of my life I won’t get back. So just in case any one else has to go through this I pulled all the Oracle scripts for creating the tables and inserting the data, zipped them up and have made them available to you for download. All you have to do is download it, unzip it and run the scripts. Why? Because I am a nice guy that way and I had the time.  If I saved anyone some time, it was worth it.

, , ,

1 Comment

WCF and Email Attachments

First off I want to apologize for being away so long. It has been a crazy ride to say the least.

So a colleague of mine ran into an issue with WCF and emailing attachments and asked for help. In this block of code below it would always fail at:

Attachment attachment = new Attachment(fileAttachment.ContentStream, fileAttachment.Name);”     The error is : “Value cannot be null.
Parameter name: stream”

 

 

 
EmailSendInput emailSendInput = new EmailSendInput
                {
                    Attachments = new List<Attachment>(),
                    Body = model.Body,
                    To = new List<string> { model.EmailTo },
                    From = model.EmailFrom,
                    Subject = model.EmailSubject
                };

                if (model.Files != null)
                {
                    foreach (var currAttachment in model.Files)
                    {
                        if (currAttachment != null && currAttachment.ContentLength > 0)
                        {
                            // the filename needs to be nice looking
                            string fileName =
                                currAttachment.FileName.Substring(
                                    currAttachment.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) + 1,
                                    currAttachment.FileName.Length
                                    – currAttachment.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) – 1);

                            var attachment = new Attachment(currAttachment.InputStream, fileName);
                            emailSendInput.Attachments.Add(attachment);
                        }
                    }
                }

                B2BMortgageDataServiceAgent b2BMortgageDataServiceAgent = new B2BMortgageDataServiceAgent();
                EmailSendResponse emailSendResponse = b2BMortgageDataServiceAgent.SendEmail(emailSendInput);
                if (!emailSendResponse.Success)
                {
                    throw new Exception(emailSendResponse.Message);
                }
            }

public EmailSendResponse SendEmail(EmailSendInput input)
        {
            EmailSendResponse retVal = new EmailSendResponse();
            try
            {
               
                string smtpServer = “”
                string smtpPort = “”

                using (var client = new SmtpClient(smtpServer, Convert.ToInt32(smtpPort)))
                {
                    var mail = new MailMessage
                    {
                        From = new MailAddress(input.From),
                        Subject = input.Subject,
                        Body = input.Body
                    };
                    input.To.ForEach(t => mail.To.Add(t));

                    if (input.Attachments != null && input.Attachments.Count > 0)
                    {
                        foreach (var fileAttachment in input.Attachments)
                        {
                            //Code Crashes here
                            Attachment attachment = new Attachment(fileAttachment.ContentStream, fileAttachment.Name);
                            mail.Attachments.Add(attachment);
                        }
                    }

                    client.Send(mail);
                }

                retVal.Success = true;
            }
            catch (Exception exception)
            {
                retVal.Success = false;
                LogUtil.LogException(exception);

            
                retVal.Message = exception.ToString();
            }

            return retVal;
        }

and then the contract:

[DataContract]
    public class EmailSendInput
    {
        [DataMember]
        public string From { get; set; }

        [DataMember]
        public List<string> To { get; set; }

        [DataMember]
        public string Subject { get; set; }

        [DataMember]
        public string Body { get; set; }

        [DataMember]
        public List<Attachment> Attachments { get; set; }

    }

Implemented as:

public EmailSendResponse SendEmail(EmailSendInput input)
         {
             try
             {
                 return this.dataAgent.SendEmail(input);
             }
             catch (Exception e)
             {
                 this.logger.LogException(e, 2);
                 throw new FaultException(“An error occured in SendEmail. Error details : ” + this.BuildMessage(e));
             } 
         }

and the Email response:

[DataContract]
    public class EmailSendResponse
    {
        [DataMember]
        public bool Success { get; set; }

        [DataMember]
        public string Message { get; set; }
    }

So now we have the problem. I basically had to recreate his datamember for attachment in the contract EmailSendInput to a

public List<EmailEncodedAttachment> Attachments { get; set; }

and added a new contract called EmailEncodedAttachment and process how he was handling the attachment differently. I’ve also included the MVC controller calls in case it might help you as well.

 

SOLUTION:

[DataContract]
    public class EmailSendInput
    {
        [DataMember]
        public string From { get; set; }

        [DataMember]
        public List<string> To { get; set; }

        [DataMember]
        public string Subject { get; set; }

        [DataMember]
        public string Body { get; set; }

        [DataMember]
        public List<EmailEncodedAttachment> Attachments { get; set; }

    }

 

[DataContract]
    public class EmailEncodedAttachment
    {
        [DataMember]
        public string Base64Attachment;

        [DataMember]
        public string Name;

        /// <summary>
        /// One of the System.Net.Mime.MediaTypeNames
        /// </summary>
        [DataMember]
        public string MediaType;
    }
}
                retVal.Message = exception.ToString();
            }

            return retVal;
        }

 

public EmailSendResponse SendEmail(EmailSendInput input)
        {
            EmailSendResponse retVal = new EmailSendResponse();
            try
            {
               
                string smtpServer = ConfigurationManager.AppSettings[“SmtpServer”] ?? “url”;
                string smtpPort = ConfigurationManager.AppSettings[“SmtpPort”] ?? “portnum”;

                using (var client = new SmtpClient(smtpServer, Convert.ToInt32(smtpPort)))
                {
                    var mail = new MailMessage
                    {
                        From = new MailAddress(input.From),
                        Subject = input.Subject,
                        Body = input.Body
                    };
                    input.To.ForEach(t => mail.To.Add(t));

                    if (input.Attachments != null && input.Attachments.Count > 0)
                    {
                        foreach (var fileAttachment in input.Attachments)
                        {
                            mail.Attachments.Add(this.CreateAttachment(fileAttachment));
                        }
                    }

                    client.Send(mail);
                }

                retVal.Success = true;
            }
            catch (Exception exception)
            {
                retVal.Success = false;
                LogUtil.LogException(exception);
             
                retVal.Message = exception.ToString();
            }

            return retVal;
        }

 

The MVC controller action calls the service like so:

EmailSendInput emailSendInput = new EmailSendInput
                {
                    Attachments = new List<EmailEncodedAttachment>(),
                    Body = model.Body,
                    To = new List<string> { model.EmailTo },
                    From = model.EmailFrom,
                    Subject = model.EmailSubject
                };

                if (model.Files != null)
                {
                    foreach (var file in model.Files)
                    {
                        if (file != null && file.ContentLength > 0)
                        {
                            // the filename needs to be nice looking
                            string prettyFileName =
                                file.FileName.Substring(
                                    file.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) + 1,
                                    file.FileName.Length
                                    – file.FileName.LastIndexOf(@”\”, System.StringComparison.Ordinal) – 1);

                            var attachment = this.CreateAttachment(prettyFileName, file.InputStream);
                            emailSendInput.Attachments.Add(attachment);
                        }
                    }
                }

                B2BMortgageDataServiceAgent b2BMortgageDataServiceAgent = new B2BMortgageDataServiceAgent();
                EmailSendResponse emailSendResponse = b2BMortgageDataServiceAgent.SendEmail(emailSendInput);
                if (!emailSendResponse.Success)
                {
                    throw new Exception(emailSendResponse.Message);
                }

 

and finally the encoding method which makes this possible:

private EmailEncodedAttachment CreateAttachment(string fileName, Stream stream)
        {
            EmailEncodedAttachment att = new EmailEncodedAttachment
            {
                Name = fileName,
                MediaType = System.Net.Mime.MediaTypeNames.Text.Plain
            };

            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, (int)stream.Length);
            att.Base64Attachment = Convert.ToBase64String(buffer);

            return att;
        }

 

There you have it folks. I hope you have a great Sunday!

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Capture an Image of the Desktop, Specific Screen or Portion of a Screen with C#

So today is my birthday. It has been a wild ride this last 46 years. Lets hope that things continue to get better.

So this is my entire class for capturing screens and desktop appearance to an image file or to print them. I use this class quite often in my error management, saving or emailing the output should errors occur so I can get a good idea of what was going on at the time an error occurs. Why? Because often end users or business analysts, though they are trying their best, sometimes can’t describe in detail how to reproduce what occurred. I suggest using this in conjunction with a logging class as well so that you can replicate the steps needed. The image file is also very handy in reconstructing what a user was or was not doing which, as a coder, can literally save your ass on occasion. So here it is. It is well commented and pretty straight forward.

using System.Windows.Forms;
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;

public class clsScreenCapture
{
    private System.Drawing.Printing.PrintDocument Pd = new System.Drawing.Printing.PrintDocument();
    private PictureBox PicForm = new PictureBox();

    /// Creates an Image object containing a screen shot of the entire desktop
    public Image CaptureScreen()
    {
        return CaptureWindow(User32.GetDesktopWindow());
    } //CaptureScreen
    /// Creates an Image object containing a screen shot of a specific window
    public Image CaptureWindow(IntPtr handle)
    {
        int SRCCOPY = 0xCC0020;
        // get te hDC of the target window
        IntPtr hdcSrc = User32.GetWindowDC(handle);
        // get the size
        User32.RECT windowRect = new User32.RECT();
        User32.GetWindowRect(handle, ref windowRect);
        int width = windowRect.right – windowRect.left;
        int height = windowRect.bottom – windowRect.top;
        // create a device context we can copy to
        IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
        // create a bitmap we can copy it to,
        // using GetDeviceCaps to get the width/height
        IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
        // select the bitmap object
        IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
        // bitblt over
        GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY);
        // restore selection
        GDI32.SelectObject(hdcDest, hOld);
        // clean up
        GDI32.DeleteDC(hdcDest);
        User32.ReleaseDC(handle, hdcSrc);

        // get a .NET image object for it
        Image img = Image.FromHbitmap(hBitmap);
        // free up the Bitmap object
        GDI32.DeleteObject(hBitmap);

        return img;
    } //CaptureWindow
    /// Captures a screen shot of a specific window, and saves it to a file
    public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
    {
        Image img = CaptureWindow(handle);
        img.Save(filename, format);
    } //CaptureWindowToFile
    /// Captures a screen shot of a specific window, and saves it to a file
    public void CaptureWindowToPrinter(Form mfForm, ImageFormat format)
    {
        // Dim img As Image = CaptureScreen()

        Image img = CaptureWindow(mfForm.Handle);
        try
        {
            PicForm.Image = img;
            if (MessageBox.Show(“Press Yes to Print or No to Copy to your Clipboard (‘No’ will allow pasting into an email or Word document etc).”, “Print or Copy to Clipboard?”, MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                Pd.Print();
            }
            else
            {
                Clipboard.SetDataObject(img, true);
            }
        }
        catch (Exception ex)
        {
            string a = “vfdgsfg”;
        }
    } //CaptureWindowToPrinter
    private void pd_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        //—————————————————————
        // this procedure handles events raised by the printer object pd
        //—————————————————————
        e.Graphics.DrawImageUnscaled(PicForm.Image, 0, 0); //send image to printer – upper left position

        e.HasMorePages = false; //this is the last page to print

    }

    /// Captures a screen shot of the entire desktop, and saves it to a file
    public void CaptureScreenToFile(string filename, ImageFormat format)
    {
        Image img = CaptureScreen();
        img.Save(filename, format);
    } //CaptureScreenToFile
    public Bitmap CaptureDeskTopRectangle(Rectangle CapRect, int CapRectWidth, int CapRectHeight)
    {
        /// Returns BitMap of the region of the desktop, similar to CaptureWindow, but can be used to
        /// create a snapshot of the desktop when no handle is present, by passing in a rectangle
        /// Grabs snapshot of entire desktop, then crops it using the passed in rectangle’s coordinates
        clsScreenCapture SC = new clsScreenCapture();
        Bitmap bmpImage = new Bitmap(SC.CaptureScreen());
        Bitmap bmpCrop = new Bitmap(CapRectWidth, CapRectHeight, bmpImage.PixelFormat);
        Rectangle recCrop = new Rectangle(CapRect.X, CapRect.Y, CapRectWidth, CapRectHeight);
        Graphics gphCrop = Graphics.FromImage(bmpCrop);
        Rectangle recDest = new Rectangle(0, 0, CapRectWidth, CapRectHeight);
        gphCrop.DrawImage(bmpImage, recDest, recCrop.X, recCrop.Y, recCrop.Width, recCrop.Height, GraphicsUnit.Pixel);
        return bmpCrop;
    }
    /// Helper class containing Gdi32 API functions
    private class GDI32
    {
        public int SRCCOPY = 0xCC0020;
        // BitBlt dwRop parameter
        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”BitBlt”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 BitBlt(IntPtr hDestDC, Int32 x, Int32 y, Int32 nWidth, Int32 nHeight, IntPtr hSrcDC, Int32 xSrc, Int32 ySrc, Int32 dwRop);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”CreateCompatibleBitmap”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, Int32 nWidth, Int32 nHeight);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”CreateCompatibleDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”DeleteDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 DeleteDC(IntPtr hdc);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”DeleteObject”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 DeleteObject(IntPtr hObject);

        [System.Runtime.InteropServices.DllImport(“gdi32.dll”, EntryPoint=”SelectObject”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);
    } //GDI32
    /// Helper class containing User32 API functions
    public class User32
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        } //RECT

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”GetDesktopWindow”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr GetDesktopWindow();

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”GetWindowDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern IntPtr GetWindowDC(IntPtr hwnd);

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”ReleaseDC”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

        [System.Runtime.InteropServices.DllImport(“user32.dll”, EntryPoint=”GetWindowRect”, ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
        public static extern Int32 GetWindowRect(IntPtr hwnd, ref RECT lpRect);

    } //User32

    public clsScreenCapture()
    {
        SubscribeToEvents();
    }

// event handler wireups:
    private bool EventsSubscribed = false;
    private void SubscribeToEvents()
    {
        if (EventsSubscribed)
            return;
        else
            EventsSubscribed = true;

        Pd.PrintPage += pd_PrintPage;
    }

}


Join me on Facebook

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Get CPU Usage of a Process using C#

This was a fun assignment. I was asked to write a piece of code that when a particular process id was passed to it it would return its CPU usage. WMI is fun. Have a great night….

public static decimal GetUssage(string pid)
{
//get the process
ManagementObjectSearcher searcher = new ManagementObjectSearcher(“SELECT * FROM Win32_Process WHERE ProcessID = ” + pid);
decimal PercentProcessorTime = 0;
foreach (ManagementObject queryObj in searcher.Get())
{
DateTime firstSample, secondSample;

//populate the process info
firstSample = DateTime.Now;
queryObj.Get();
//get cpu usage
ulong u_oldCPU = (ulong)queryObj.Properties[“UserModeTime”].Value
+ (ulong)queryObj.Properties[“KernelModeTime”].Value;
//sleep to create interval
System.Threading.Thread.Sleep(1000);
//refresh object
secondSample = DateTime.Now;
queryObj.Get();
//get new usage
ulong u_newCPU = (ulong)queryObj.Properties[“UserModeTime”].Value
+ (ulong)queryObj.Properties[“KernelModeTime”].Value;

decimal msPassed = (decimal)(secondSample – firstSample).TotalMilliseconds;

//formula to get CPU ussage
if (u_newCPU > u_oldCPU)
PercentProcessorTime = (decimal)((u_newCPU – u_oldCPU)
/ (msPassed * 100 * Environment.ProcessorCount));

Console.WriteLine(“processor time ” + PercentProcessorTime);
}
return PercentProcessorTime;
}

, , , ,

Leave a comment

How to make Linq and IList sort Dynamically using C#

I apologize that it has been a while. I have been extremely busy and in the time that I have been away I went through treatment for a medical issue. Needless to say I had other issues to deal with other than this blog. But I will try to publish more frequently. Today’s topic was a question from another developer which was to have have a Linq and IList sort dynamically. So long as you don’t force execution by using ToList, you can keep tacking on to your query until you are ready to actually run it. This is because much of LINQ uses “deferred execution”. For example, you could do something similar to:

var query = apps.AsQueryable()
.Select
(Application => new
{
ID = Application.ApplicationId,
Force = Application.Force.Description,
Function = Application.BusinessFunction.Description,
Category = Application.Category.Description,
SubCategory = Application.SubCategory.Description,
Name = Application.ApplicationName,
Description = Application.ApplicationDescription
}
).Take(10);

switch (sortType)
{
case “ID”:
query = query.Orderby(Application => Application.ApplicationId);
break;
case “Force”:
query = query.Orderby(Application => Application.Force);
break;
}

IList tempList = query.ToList();

As always it has been great getting your all feedback while I was gone. Thank You! Smile

, , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Convert Visio Pages to Images in vb.net

I have been fooling around with Visio automation since attempting to help a friend with a project that did so. In the course of this I did this code snippet to convert the Visio page to an image. The code loops through and takes each page and converts it to an image. Pretty basic. I have not posted in a while and my apologies to those of you who were wondering…. Smile

Here is the code….

Sub SaveAsImage()
‘ creates an invisible Visio instance, opens a document, then
‘ saves all pages in the document as jpg images using
‘ page name and page number as file name
 
    Dim vsoApp As Visio.Application
    Dim vsoDoc As Visio.Document
    Dim PathName As String, jpgName As String
    Dim pg As Visio.Page
  
    Set vsoApp = CreateObject(“Visio.InvisibleApp”)
    ‘ SET PATH/FILENAME BELOW TO VSD ON YOUR SYSTEM
    Set vsoDoc = vsoApp.Documents.Open(“c:\TEST\test.vsd”)
  
    PathName = vsoApp.Documents(1).Path      ‘ Set pathname to that of first document
           
    For Each pg In vsoApp.ActiveDocument.Pages
        jpgName = PathName & Format(pg.Index, “0#”) & ” ” & pg.Name & “.jpg”
        pg.Export jpgName
    Next
   
    vsoDoc.Close
    vsoApp.Quit
    Set vsoDoc = Nothing
    Set vsoApp = Nothing
 
End Sub

, , , , , , , , , , , , , , , , , , , , , , , ,

2 Comments

Fluent C# Review : Chapter Three

I am reviewing an advanced copy of the book Fluent C# by noted .NET author Rebecca Riordan.

My focus today will be on chapter three. Chapter three picks up where chapter two left off  in describing the Visual Studio environment. It does an excellent job of reviewing the more intricate details of Visual Studio. Again, it ignores winforms and focuses on the Windows Presentation Foundation (WPF) forms and design editor. Encouraging the reader to customize the interface for themselves, it shows how to do that. I certainly have not seen that done before so early on in the process and in such an easygoing manner. It ends the first section explaining what Intellisense is. Later on in this chapter it goes into how members are listed. An excellent tutorial on refactoring and such is also discussed. It’s possible this discussion could have waited a bit until later on but it still works here.

We then move on to cover what a Visual Studio solution and project is and what it contains including a very helpful diagram, as they seem to always do in this book, explaining what the relationship between the various items in a Visual Studio solution and project are.

image

The next section introduces designer and source files, resources and your design documents. Covering how to add items to a solution or project comes next along with a graphical and step by step process of how to modify project properties. Changing the icon and window property is one such example they cover. Then we build the application to see the results of the changes.

Further customization of the Visual Studio environment is then discussed in the usual graphical and step by step nature this book is so good at.

image

Overall I wish I had had a book like this when I first started using Visual Studio so many eons ago!

The next chapter gets into debugging and deploying an application. Moving right along the user shouldn’t be overwhelmed with this patient, easy going manner of teaching.

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment

Fluent C# Review : Chapter Two

I am reviewing an advanced copy of the book Fluent C# by noted .NET author Rebecca Riordan.

My focus today will be on Chapter Two. Chapter Two gets into some of the nuts and bolts of the .NET Framework and writes the initial “Hello World” application that these beginner books almost always do. They begin by putting up a very nice illustration of how .NET works. Truly I have not seen it explained in such a way before!

image

They give you a little quiz on what you picked up.

Then there is an explanation of why the .NET Framework is a better way to go than say a Visual Basic 6 way of thinking. I am not sure that to a beginner programmer they understand or need to know any of this. But they certainly make good points. Being an old VB6 and VBA programmer myself I certainly could appreciate what was said.

Then they proceed into building the first application. But there is a little twist. Riordan chooses to not even bother with winforms and instead chooses to plow right into a Windows Presentation Foundation (WPF) application. At first the choice seemed odd to me. But as I considered it this makes sense. WPF is the future. Winforms is dying. It’s a sad truth but it is what it is.

Riordan walks you through the process of creating a WPF application in Visual Studio 2010 while beautifully illustrating how to do that task.

image

Then the first example of modifying a property in the WPF gui is introduced. Really it is quite well done. The appropriate message box appears saying “hello world!” is displayed. She tells the user to take a break and congratulates them on their first application. She then displays and explains the code editor in the same easy going manner. Another note that often goes on through out this book she often gives the novice programmer fun little facts to digest, so as to have fun while learning. Imagine that! C# learning being made fun!

We will be covering Chapter Three in the next entry where the Visual Studio interface will be reviewed in more detail.

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

1 Comment

Fluent C# Review : Chapter One

I am reviewing an advanced copy of the book Fluent C# by noted .NET author Rebecca Riordan.

My focus today will be on Chapter One. Chapter One opens with an introduction to what application development is. It takes the reader through the simple problem of a messy paper stack and through a picture flow chart attempts to show the reader how the problem is to be solved and equate it with the same process of writing a windows application. It is unlike anything you have ever seen in a development book! But it is also one of the most clear renderings of the application process that I have seen.

image

They introduce you to the “clients” that are to appear throughout the book, two cooks named Neil and Gordon. (Incidentally the editor happens to be named Neil….coincidence? I think not!). It encourages you to take breaks at certain strategic points throughout the book as well. Neil and Gordon hand out their requirements and Riordan helps you get through it. She even begins the process of explaining the Agile software development methodology. It then introduces UML (Unified Modeling Language) and why it should be used. That and Agile are actually advanced topics perhaps left to a later time but I get why they do it here.

In the first project the book attempts to take you down the path of creating your requirements but before you see a single line of code you see the requirements explained in an easy to understand real life example. Then before you know it you have been introduced to database schemas, class diagrams and screen layout concepts all really done in a beautifully illustrated way. Extremely well done!

When there are words that need to be defined they are set out like so, so that they stand out from the rest of the page (see example below). Again hard to miss and it really catches the eye.

image

It goes into JIT (Just in Time Debugging) and the CLR (common language runtime) explaining what it is and how it is used. Of course at the end there is the obligatory review of the chapter. The only difference is this one is beautifully illustrated.

I don’t know about you but I am certainly looking forward to chapter two as we get more into the nuts and bolts of what is happening.

, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Leave a comment