Archive for the ‘Development’ Category.

How to copy a directory recursively in C#?

Today I had the task of copying a directory recursively in C#. The first thing I did was type into my project “Directory.” and see if intellisense brought up a function called Directory.Copy. Unfortunately there is not a Directory.Copy, which to me seems like an oversight, as copying a directory is fairly common. Maybe it is not an action commonly done in C#.

So next I went to my browser and did a search. Well, I am not the first, nor will I be the last to solve this. There are a number of solutions online and each seem to have both positive and negative comments.

Option 1 – A directory copy using recursion

Pros: This is simple and to the point and elegant.

Cons: One complaint is that this could cause a stack overly by using recursion but this might not be a valid con as the filesystem restrictions in Windows might prevent a stack overflow anyway.

Since I am dealing with a small controlled tree, the con will not affect me., but since we are dealing with a file system, this is likely not to occur.

        private static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target)
        {
            foreach (DirectoryInfo dir in source.GetDirectories())
                CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
            foreach (FileInfo file in source.GetFiles())
                file.CopyTo(Path.Combine(target.FullName, file.Name));
        }

Option 2 – Use SearchOption.AllDirectories to create the directory structure then then copy all the files

Pros: Does not use recursion
Cons: Are there any?

        private static void CopyFilesRecursively(String SourcePath, String DestinationPath)
        {
            // First create all of the directories
            foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories))
                Directory.CreateDirectory(dirPath.Replace(SourcePath, DestinationPath));

            // Copy all the files
            foreach (string newPath in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories))
                File.Copy(newPath, newPath.Replace(SourcePath, DestinationPath));
        }

Option 3 – Use one of the methods recommended by MSDN

Unfortunately MSDN is not consistent, and recommends two different methods in two different places, which I am sure were written by different teams.

using System;
using System.IO;

class DirectoryCopyExample
{
    static void Main()
    {
        DirectoryCopy(".", @".\temp", true);
    }

    private static void DirectoryCopy(
        string sourceDirName, string destDirName, bool copySubDirs)
    {
      DirectoryInfo dir = new DirectoryInfo(sourceDirName);
      DirectoryInfo[] dirs = dir.GetDirectories();

      // If the source directory does not exist, throw an exception.
        if (!dir.Exists)
        {
            throw new DirectoryNotFoundException(
                "Source directory does not exist or could not be found: "
                + sourceDirName);
        }

        // If the destination directory does not exist, create it.
        if (!Directory.Exists(destDirName))
        {
            Directory.CreateDirectory(destDirName);
        }

        // Get the file contents of the directory to copy.
        FileInfo[] files = dir.GetFiles();

        foreach (FileInfo file in files)
        {
            // Create the path to the new copy of the file.
            string temppath = Path.Combine(destDirName, file.Name);

            // Copy the file.
            file.CopyTo(temppath, false);
        }

        // If copySubDirs is true, copy the subdirectories.
        if (copySubDirs)
        {

            foreach (DirectoryInfo subdir in dirs)
            {
                // Create the subdirectory.
                string temppath = Path.Combine(destDirName, subdir.Name);

                // Copy the subdirectories.
                DirectoryCopy(subdir.FullName, temppath, copySubDirs);
            }
        }
    }
}

Or the different one they posted here:

using System;
using System.IO;

class CopyDir
{
    public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
    {
        if (source.FullName.ToLower() == target.FullName.ToLower())
        {
            return;
        }

        // Check if the target directory exists, if not, create it.
        if (Directory.Exists(target.FullName) == false)
        {
            Directory.CreateDirectory(target.FullName);
        }

        // Copy each file into it's new directory.
        foreach (FileInfo fi in source.GetFiles())
        {
            Console.WriteLine(@"Copying {0}\{1}", target.FullName, fi.Name);
            fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
        }

        // Copy each subdirectory using recursion.
        foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
        {
            DirectoryInfo nextTargetSubDir =
                target.CreateSubdirectory(diSourceSubDir.Name);
            CopyAll(diSourceSubDir, nextTargetSubDir);
        }
    }

    public static void Main()
    {
        string sourceDirectory = @"c:\sourceDirectory";
        string targetDirectory = @"c:\targetDirectory";

        DirectoryInfo diSource = new DirectoryInfo(sourceDirectory);
        DirectoryInfo diTarget = new DirectoryInfo(targetDirectory);

        CopyAll(diSource, diTarget);
    }

    // Output will vary based on the contents of the source directory.
}

Option 4 – Use Microsoft.VisualBasic

Pros: One line.
Cons: You have to reference an additional dll that you otherwise do not need.
This additional dll is not available in Mono for cross-platform development.

new Microsoft.VisualBasic.Devices.Computer().
    FileSystem.CopyDirectory( sourceFolder, outputFolder );

There are various other methods:

Resources:
http://stackoverflow.com/questions/58744/best-way-to-copy-the-entire-contents-of-a-directory-in-c
http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.aspx
http://msdn.microsoft.com/en-us/library/bb762914.aspx
http://xneuron.wordpress.com/2007/04/12/copy-directory-and-its-content-to-another-directory-in-c/
http://www.logiclabz.com/c/copy-directory-in-net-c-including-sub-folders.aspx

A quick overview of MVVM

Model View ViewModel (MVVM) is a design pattern based on Model View Controller (MVC) but specifically tailored to Windows Presentation Foundation (WPF).

MVVM is not a framework per se but many frameworks have been created. Here is a list of MVVM Frameworks from Wikipedia.

See the Wikipedia site here: Open Source MVVM Frameworks.

Another blog, has some basic information on many of these here: A quick tour of existing MVVM frameworks

A framework is actually not necessary to implement MVVM and you should seriously consider whether using one is right for your WPF application or not. Many applications do not need much of the features the frameworks provide. However, there are two common classes that all MVVM frameworks contain. These are ViewModelBase and RelayCommand. Though some frameworks may give them different names or implement them slightly differently, they all have these classes. For example, MVVM Foundation names the ViewModelBase differently. It is called ObservableObject, which is more appropriate because it is incorrect to assume that all objects that implement INotifyPropertyChanged are going to be ViewModel objects.

Instead of installing and using an MVVM framework, you could simply include these classes in your application, as these are all you need to implement MVVM.

  • ObservableObject
  • RelayCommand

While these two classes are enough, you may want to investigate how different MVVM Frameworks implement and what else they implement and why. You may find that another feature implemented is exactly what you need in your application and knowing about it could save you time.

The 8 Types of Technical Documentation and Why Each Is Important

Technical documentation is critical to the success of any software. However, most creators of software struggle to provide adequate documentation for their product. Rare is the software that is praised for its documentation. When documentation is praised, it is often only praised for having some documentation, which is more than most, but in reality documentation is usually still inadequate.

So what constitutes adequate documentation? Well, if a user wants to do something with your software and the documentation helps them succeed in a timely manner, then the documentation is adequate. However, accomplishing this is not as easy as it sounds.

Why most companies fail to document properly

Most companies do not document their product thoroughly for a few reasons.

  • Lack of a defined list of all types of documentation
  • Lack of understanding of each type of documentation
  • Documentation is not made a priority and lacks of funding

Lack of a defined list of all types of documentation

Many cannot name more than one or two forms of documentation. To be successfully with documentation, a software company must first enumerate the types of documentation. Then it must learn about each type of documentation and understand the role that each type of documentation plays. It is also critical to understand the different target audiences each type has. Also, what are the common mistakes made when trying to create each type of documentation so these mistakes can be avoided.

Attempts are made to document software in different ways. However, because a complete documentation set is not defined, success is nearly impossible. To make matters worse, there is little to no reporting or visibility into the level of documentation a given piece of software has. I have never encountered software that has reached a 100% documentation level.

In order to succeed there must be an understanding of the types of documentation.

  1. Step-by-Step Walk-thrus – Also called Guides, How to’s, or Examples, Quick Start Guides
  2. Product feature documentation – This is lists all the features and settings without really any real world examples. Often the help button inside the software points to sections of this document.
  3. Troubleshooting Documentation – What to do when a failure occurs. Where are the logs and how to read them. How to turn on or increase logging and debugging.
  4. Knowledge-base (Problem, Cause, Resolution), Frequently Asked Questions (FAQ), and Forums
  5. Code, API, or SDK Documentation
  6. Internal Development Documentation – Such as code and development documentation, internal only features use by developers and/or testers, architecture documentation (Note: For open source projects this information is usually public)
  7. Real life customer implementations – Examples of how a company has a product implemented in real life
  8. Marketing documentation – Basic over views of the value the software has for the company, ROI claims, general feature lists, costs, etc…

The worst documentation of all is of course the absence of documentation. However, most software companies are unaware that there are entire areas of documentation that are lacking. To have complete documentation you must provide it in all of these areas.

Lack of understanding of each type of documentation

Since most software companies are unaware of the list above, it makes sense that they don’t understand the items on the list. This is why they have no direction and their documentation is a sporadic combination of the different documentation types, never fully succeeding to accomplish the primary goal of documentation, which is to enable the reader to succeed.

In order to create excellent documentation, a full understanding of each type of documentation is requisite. Without this understanding, documentation your documentation will continue to be lacking.

The lack of understanding also leads to assumptions that are not true. Some think that if they try to document every setting their software has they will have complete documentation. Usually when this is done, there is so much effort put into this that providing a simple example is forgotten. Often I hear this question:

Why would an example be needed, every feature is documented?

I would answer this question as follows:

Information overload. Now there is so much documentation in one white paper that someone who wants to do something simple is unsure that it is simple. They don’t know which features they must setup and which are unnecessary or should remain as defaults.

I often find this with Open Source documentation and unfortunately when a user asks for an example they are often rudely told to “Read the Manual” or RTM. However, the manual is usually hundreds of pages and they probably need to read one page of the manual but just don’t know where to start.

If have seen documentation using only examples as well. However, when an attempt is made to deviate from the examples, there is nothing left in the documentation to provide the guidance necessary to succeed.

Some documentation is better defined, such as that created from the results of support calls, forums, or mailing lists. Because this type of documentation is completely reactionary, this is one area of documentation that is better defined. The documentation is created after a problem is experienced and has to be dealt with. However, once created, it exists to benefit others. As this documentation type is better defined you might not be surprised to know that it has its own acronym: KCS or Knowledge Centered Support.

The goal of this article is to raise awareness of all types of technical documentation and make them all as well-defined as support documentation.

Documentation is not made a priority and lacks of funding

Investing in documentation is expensive. But it is usually and expense that pays off. If an analyst has to choose between two competing software applications and one is well documented and one is not, the well documented software application is likely to be chosen. Many organizations fail to see the ROI in documentation and therefore choose not to invest.

It is obviously that lack of funding for documentation is an industry wide phenomenon. While technical writing has been around since even before software, a standard for documentation whether it be creating documentation, updating documentation, managing documentation, and reporting on documentation has yet to formally exist. However, I did find this link, which shows I am not the only one who has identified this problem: http://www.hci.com.au/iso/

So lets get back to our list. Below I will go through each type of documentation and provide some information on it.

Type 1 – Step-by-step Walk-thrus – Also called Guides, How to’s, or Examples, Quick Start Guides

Description

This type of documentation is nothing more than actions that the reader will take to accomplish something with your software. This documentation, when done right, could be followed by the most computer illiterate. If they read and follow each step, even if they have no idea what they are doing, they should succeed.

You may also want to read: Your project’s ‘Getting Started’ tutorial sucks – Why time to success matters

Role

To provide the most common, most tested, most successful, and best overall example of how to accomplish some particular task from start to finish with your software.

Audience

Most commonly, trainees and new or evaluation users. However, anyone who wants to achieve the results the step-by-step guide leads to is included. This is most often, but is not limited to, users of your software. It includes deployment engineers, configuration specialists, support engineers, and demo or sales engineers.

Common Article Names

  • Quick Start Guide
  • Step-by-step Guide for setting up “Software X”
  • How to configure “Some Feature” of “Software X”

Common mistakes

There are many common mistakes

  • Not clearly defining the starting point of the walk-thru. Think of the starting point of a software that installs on Windows. What version of Windows, what other software must be installed, etc…
  • Defining the starting point clearly, but using a starting point most people don’t know how to get to. For example, you starting point should probably not say “have SQL Server installed and a database created with credentials” without providing steps.
  • Assuming the reader knows how to accomplish a task, so the documentation simply states to “do task x” instead of walking the reader through doing the task.
  • Skipping steps or forgetting steps.
  • The development department changes the steps just before release but the documentation is not updated to match.
  • Trying to simultaneously provide Product Feature Documentation in the middle of your steps. A link or note is acceptable for steps or settings that customers commonly customize.
  • Trying to provide comprehensive troubleshooting documentation after each step. It is great to have a link or a reference to troubleshooting documentation but it shouldn’t interfere with the walk-thru.
  • Only creating step-by-step guides for a couple common features of your software.
  • Failing to add documentation after use. For example, when a consultant, support engineer, or other employee struggles to set up a not-well-documented feature and once successful, they still don’t document it.

Type 2 – Product feature documentation

Description

This type of documentation is a description of every feature and setting. What it is used for, when and why one would use the feature or setting.

Role

This is for users who need to stray from the common walk-thrus and need to know what alternate and uncommon settings are used for so they can determine which they need in their particular environment.

Audience

Any customer/user who needs more than the most common features. Your own support representatives and architect or professional services teams. Consultants who recommend your product or are trusted to determine if your product meets a feature set for potential customers/users.

Common Article Names

  • The Software X Handbook
  • Software X: The Complete Reference
  • Understanding Feature Y of Software X

Common mistakes

  • Burying the features in other documentation, such as walk-thrus.
  • Not including at least a comment about when the feature would be used.
  • Not being aware of the features your customers/users are aware of and using. There are lots of “unintended features” and you should capture them in documentation.
  • Not letting customers contribute to this documentation in some way, even if it is just comments (this is the best way to solve the above issue, too).

Type 3 – Troubleshooting documentation

Description

This documentation describes steps to diagnose problems. It includes information on logs files. It includes information on the behind the scenes business your software is doing, such as process/thread work, file or data interaction, etc…

If the users tries to do some task with your software and it fails, to them, a single task failed. However, to fix it, one might need to know that behind the scenes ten different processes occurred. It is important to be able to diagnose which background processes worked and pinpoint which one failed, so you don’t troubleshoot all ten background processes when only maybe the seventh is the problem.

Role

To help customers/users get pasts unexpected issues and to help support engineers diagnose issues. These don’t have to always be public, but should be in the hands of your support engineers.

Audience

This is for support engineers more than customers, though the more experienced and “get your hands dirty” customers/users will use it. Engineers who do on site installation or on site configuration may need this information for when they run into bumps.

Common Article Names

  • Feature X: The complete troubleshoot guide
  • Troubleshooting Feature X

Common mistakes

  • Confusing “Problem, Cause, Resolution” documentation (also called Knowledge Base articles) with Troubleshooting documentation.
  • Not creating this documentation because you assume product feature documentation covers this. It doesn’t.
  • Providing this documentation but not providing complete troubleshooting steps for whatever reason. Especially if troubleshooting is done with 3rd party software and outside your own product it is assumed outside the scope when it is not. For example, a product that requires a DNS server, should provide steps to make sure that a DNS server is configured as the product expects. You may not have to write such documentation if the 3rd party vendor has some, but you should link to/reference it in your own documentation.
  • Writing documents that have lists of “fixes to try”. This documentation should almost never include “fixes”, but instead should diagnose the issue or pinpoint the problem so precisely that the fix becomes obvious whether the fix currently exists or not.

Type 4 – Knowledge-base (Problem, Cause, Resolution)

Description

This documentation is most commonly the result of customer support tickets/cases. It lists a specific problem, a specific cause of the problem, and a single resolution to that problem. As mentioned early this is one of the more well-defined areas of documentation. Read more here about KCS or Knowledge Centered Support.

Role

To make it so an issue only has to be troubleshot and fixed once. Once an issue is fixed, the Problem, Cause, Resolution can be documented and the fix can be applied without troubleshooting when the same Problem and Cause occurs.

To keep knowledge in-house. Tech Support is a high turnover position so keeping knowledge in-house is not always the easiest task.

Audience

Customers who experience a problem. Support engineers or other employees to whom the problem is reported.

Common Article Names

Frequently Asked Questions or FAQ.

Common Issues.

Common mistakes

  • Providing multiple Problems, Causes, or fixes in the same article.
  • Providing a problem and a list of fixes with no way to determine which fix is the correct fix.
  • Having an article that recommends a fix even when a customer is not really having that problem.
  • Failing to provide a good search for the knowledge base articles.

Type 5 – Code, API, or SDK Documentation

Description

This documentation describes how others use your code or libraries to write add-ons, plugins, integration, or otherwise customize your application through code. Do not confuse this with Internal Development Documentation. This type is for external users or resellers or middle-ware companies.

Role

This documentation helps others code with your code and libraries. Software that a customer/user takes the time and expense to modify to fit their environment becomes “sticky”, meaning the customer/user is likely to be loyal.

Audience

Systems Analyst / Developers / Integration Engineers / Middle-ware companies / Resellers. Customers who need to extend your product to meet a business need. Or in an open source environment, how others can use your code to extend their own project.

Common Article Names

  • Software X SDK Documentation
  • Class or Function Reference for Software X API

Common mistakes

  • Providing zero documentation on this
  • Providing incorrect documentation about a function
  • Updating code but not updating the documentation
  • Deprecating code but not informing the consumer
  • Not providing the first type of documentation: Samples, walk-thrus, etc…

Type 6 – Internal Development Documentation

Description

This is used for internal developers continue future enhancements and otherwise maintain a piece of software.

Role

To help developers work with a piece of code. To overcome turnover so new developers can pick up code another developer created. To provide architecture and design of each piece of code. To give UML (usually the classes and their methods),

Audience

Internal developers. Sometimes support.

Common Article Names

There are really no common names, but usually these types of documentation are internal only.

Common mistakes

  • Not writing such documentation at all.
  • Not documentation all parts of the code: Classes, Functions, design and architecture, supported features, etc…

Type 7 – Real life customer implementations

Description

This is documentation about customers success stories. About how they implemented your software in their environment (which is usually as messed up as everyone else’s environments).

Role

To demonstrate that the software can be successful and has proven itself in real life customer environments.

Audience

Other customers / System Analysts / Internal Employees in charge of future enhancements and road maps

Common Article Names

  • Product X Success Stores
  • How Company Y succeeded with Product X

Common mistakes

  • Not providing any customer success stories.
  • Providing success stories from unhappy customers who when contacted, speak poorly of your product

Type 8 – Marketing documentation

Description

This is documentation that doesn’t really say much more than is needed to let a customer know about a software solution.

Role

To acquire more customers. To help potential customers determine features sets quickly.

Audience

Systems Analysts / Consultants / Sales Engineers / Evaluation customers.

Common Article Names

  • Product X
  • The Product X Feature Set
  • What Product X can do for you business

Common mistakes

I don’t know a lot of the mistakes made in this documentation type, as my exposure to marketing is limited. I almost forgot this documentation type.

  • Too complex, including information or overly complex images or diagrams that are hard to understand

Conclusion

Hopefully after reading this article, you have a greater understanding of documentation.

Now that you know all the types of documentation, there are other problems to address. How to write the documentation. How to choose the priority for writing these types of documentation. How to balance the cost of documentation against the opportunity cost of not having documentation.

Some day, I will also have to write a post on how to deal with “versioning” documentation including updating documentation when Software versions change. I think there is a market for a piece of software that does nothing but track documentation. Hopefully it is well documented. 🙂

The Array class in C#

System.Array is an important class to know and understand as almost any programming work has arrays.

Array is an abstract class, so you cannot establish and instance of it. That is OK because it is really just a “function holder” class.  The term “function holder” is not an official C# term, but it is a name I give classes that really just exist to hold functions.  Array is a “function holder” for array functions.

Lets take a moment to learn a few of the functions in the Array class. We are going to use an array of high scores to learn from.

Array.Sort

Let start by creating an array of high scores. The following code has a function that takes a score and adds it to the list if it is greater than the lowest high score and sorting them.

using System;

namespace ArrayLearning
{
    class Program
    {
        static int[] highScores = new int[12];

        static void Main(string[] args)
        {
            // keep that top 12 high scores
            AddScore(10100);
            AddScore(13710);
            AddScore(14190);
            AddScore(12130);
            AddScore(12130);
            AddScore(16140);
            AddScore(19320);
            AddScore(07250);
            AddScore(18140);
            AddScore(08090);
            AddScore(10010);
            AddScore(14380);
            AddScore(18140);
            AddScore(12190);
            AddScore(19320);
        }

        static void AddScore(int newScore)
        {
            // Pre-sort the high scores in case somehow the
            // first one is not the lowest.
            Array.Sort(highScores);

            // If the new score is greater than the lowest
            // high score, replace the lowest high score
            if (highScores[0] < newScore)
                highScores[0] = newScore;

            // Now resort the scores as the new score may
            // not be in the right place
            Array.Sort(highScores);

            DisplayHighScores();
        }

        private static void DisplayHighScores()
        {
            // Print the new high scores
            for (int i = highScores.Length - 1; i > -1; i--)
            {
                Console.WriteLine(highScores[i]);
            }
            Console.WriteLine("Press any key to continue");
            Console.ReadKey();
            Console.WriteLine();
        }
    }
}

Ok, I am not saying this is the proper way to handle high scores in a game.  I am just demonstrating Array.Sort for you.

Array.Clear

Ok, lets show an example of Array.Clear. This is a very simple function that sets all the values in the array to their default value. Booleans have a default value of false. Double, Int32, Int64, etc, have a default value of 0. Reference types have a default value of null.

Here is an enhancement to the above snippet that allows demonstrates clearing an entire array. Notice Array.Clear takes the array, then the starting item in the array and the number items in the array. In this example we clear the entire array, but that is not required.

using System;

namespace ArrayLearning
{
    class Program
    {
        static int[] highScores = new int[12];

        static void Main(string[] args)
        {
            // keep that top 12 high scores
            AddScore(10100);
            AddScore(13710);
            AddScore(14190);
            AddScore(12130);
            AddScore(12130);
            AddScore(16140);
            AddScore(19320);
            AddScore(07250);
            AddScore(18140);
            AddScore(08090);
            AddScore(10010);
            AddScore(14380);
            AddScore(18140);
            AddScore(12190);
            AddScore(19320);

            // Clear the high scores
            ClearHighScores();
        }

        static void AddScore(int newScore)
        {
            // Pre-sort the high scores in case somehow the
            // first one is not the lowest.
            Array.Sort(highScores);

            // If the new score is greater than the lowest
            // high score, replace the lowest high score
            if (highScores[0] < newScore)
                highScores[0] = newScore;

            // Now resort the scores as the new score may
            // not be in the right place
            Array.Sort(highScores);

            DisplayHighScores();
        }

        public static void ClearHighScores()
        {
            Console.WriteLine("Clearing High Scores!");
            Array.Clear(highScores, 0, highScores.Length);
            DisplayHighScores();
        }

        private static void DisplayHighScores()
        {
            // Print the new high scores
            for (int i = highScores.Length - 1; i > -1; i--)
            {
                Console.WriteLine(highScores[i]);
            }
            Console.WriteLine("Press any key to continue");
            Console.ReadKey();
            Console.WriteLine();
        }
    }
}

Array.IndexOf

Maybe you want to display the place in the top 12 that the player scored. However, the way we are adding the score does not track the new score’s place. So we need to find the place. Here is a small enhancement to the above code that demonstrates the use of Array.IndexOf to find the place.

Notice the addition of the DisplayCurrentPlace function and it’s use of Array.IndexOf. Also since the array is actually sorted with the lowest number at index 0 and the highest score at index 11, I can just subtract the index from the max lengh of 12 high scores to get the correct place.

using System;

namespace ArrayLearning
{

    class Program
    {
        public static int MAX = 12;
        static int[] highScores = new int[MAX];

        static void Main(string[] args)
        {
            // keep that top 12 high scores
            AddScore(10100);
            AddScore(13710);
            AddScore(14190);
            AddScore(12130);
            AddScore(12130);
            AddScore(16140);
            AddScore(19320);
            AddScore(07250);
            AddScore(18140);
            AddScore(08090);
            AddScore(10010);
            AddScore(14380);
            AddScore(18140);
            AddScore(12190);
            AddScore(19320);
            AddScore(06320);

            // Clear the high scores
            ClearHighScores();
        }

        static void AddScore(int newScore)
        {
            // Pre-sort the high scores in case somehow the
            // first one is not the lowest.
            Array.Sort(highScores);

            // If the new score is greater than the lowest
            // high score, replace the lowest high score
            if (highScores[0] < newScore)
            {
                highScores[0] = newScore;

                // Now resort the scores as the new score may
                // not be in the right place
                Array.Sort(highScores);

                DisplayHighScores();
                DisplayCurrentPlace(newScore);
            }
        }

        public static void ClearHighScores()
        {
            Console.WriteLine("Clearing High Scores!");
            Array.Clear(highScores, 0, highScores.Length);
            DisplayHighScores();
        }

        private static void DisplayHighScores()
        {
            // Print the new high scores
            for (int i = highScores.Length - 1; i > -1; i--)
            {
                Console.WriteLine(highScores[i]);
            }
        }

        private static void DisplayCurrentPlace(int newScore)
        {
            Console.WriteLine(String.Format("You placed number {0} out the top 12.", MAX - Array.IndexOf(highScores, newScore)));

            Console.WriteLine("Press any key to continue");
            Console.ReadKey();
            Console.WriteLine();
        }
    }
}

Well, these were three simple examples of using the Array class. As you can see it is little more than a “function holder”.

If you have an example of a function in the Array class, please post it here in the comments.

Getting better with the String and StringBuilder classes in C#

So we all use the Strings in C# and most of us consider ourselves experts.  But are we really experts.  When you’re getting tested and you don’t have Visual Studio or MSDN in front of you, are you ready to answer the questions with confidence?

Sometimes it is worth while to re-learn the basics because often simple features you are not using would save you time and prevent you from failing to appear as knowledgeable as you really are. Especially if you have not had a project where you manipulate strings, because you do other complex tasks and you do little more with strings than assign them values and compare them.

Well, here are the two links to the String and StringBuilder objects on MSDN.

Take a moment and read the MSDN pages about these objects even if you have read them before.

Here are some questions that you should answer about these classes.

  1. Which is mutable and which is immutable? What does that mean?

    Answer:

    String is immutable.  That means that once you create a string, it cannot be altered in place in memory, but instead, any alteration causes a copy with the modification to be created in a new memory location and the reference is updated to refer to the copy. For example if you append a character you actually get a whole new string in a whole new memory location.

    StringBuilder is mutable.  That means that you can change the object in place in memory without creating a copy.  For example, if you append a character to StringBuilder it can add it to the same space in memory.  There is one exception.  If you add so many characters that the next character you add make the string bigger than the memory location’s capacity, a new object in memory is created. The default capacity for this implementation is 16 characters, and the default maximum capacity is Int32.MaxValue. (1) So if you are playing with Strings greater than 16 characters, you should instantiate your StringBuilder objects with a capacity greater than 16.

  2. So can you modify a string in place in memory?

    Answer:

    No. And yes.

    Read this MSDN article: How to: Modify String Contents (C# Programming Guide)

    The short version of the above article is that you can’t normally. But if you use “unsafe” you can, the above link provides the following unsafe code:

    class UnsafeString
    {
        unsafe static void Main(string[] args)
        {
            // Compiler will store (intern)
            // these strings in same location.
            string s1 = "Hello";
            string s2 = "Hello";
    
            // Change one string using unsafe code.
            fixed (char* p = s1)
            {
                p[0] = 'C';
            }
    
            //  Both strings have changed.
            Console.WriteLine(s1);
            Console.WriteLine(s2);
    
            // Keep console window open in debug mode.
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
    

    Would you actually do this though?

  3. What is the easiest way to reverse a String?
        public static string ReverseString(string s)
        {
    	char[] arr = s.ToCharArray();
    	Array.Reverse(arr);
    	return new string(arr);
        }
    

    Notice another C# class called Array was used. This class, like String and StringBuilder, is another class that you may be forgetting about an overlooking.

    When I was asked how to reverse a string, the Array.Reverse function did not come to mind and so I recreated it with this function, which obviously takes more time and a developer’s time is too expensive to recreate work already done for you.

        private static String Reverse(String inString)
        {
            char[] myChars = inString.ToCharArray();
            for (int i = 0, j = inString.Length - 1; i < inString.Length / 2; i++, j--)
            {
                char tmp = inString[j];
                myChars[j] = inString[i];
                myChars[i] = tmp;
            }
            return new string(myChars);
        }
    
  4. Which is more efficient for concatenation or appending characters, String or StringBuilder?

    StringBuilder is by far more efficient. Microsoft has a knowledge base article on this here: http://support.microsoft.com/kb/306822

    I changed the code slightly to use the Stopwatch to time the ticks to get more accurate data.

    using System;
    using System.Diagnostics;
    
    namespace StringBuilderPerformance
    {
        class Program
        {
            static void Main(string[] args)
            {
                // The greater the loops the better the performance ratio
                const int sLen = 30, Loops = 10000;
                int i;
                string sSource = new String('X', sLen);
                string sDest = "";
                //
                // Time string concatenation.
                //
                Stopwatch timer = new Stopwatch();
                timer.Start();
                for (i = 0; i < Loops; i++) sDest += sSource;
                timer.Stop();
                long stringTicks = timer.ElapsedTicks;
                Console.WriteLine("Concatenation took " + stringTicks + " ticks.");
                //
                // Time StringBuilder.
                //
                timer.Reset();
                timer.Start();
                System.Text.StringBuilder sb = new System.Text.StringBuilder((int)(sLen * Loops * 1.1));
                for (i = 0; i < Loops; i++) sb.Append(sSource);
                sDest = sb.ToString();
                timer.Stop();
                long stringBuilderTicks = timer.ElapsedTicks;
                Console.WriteLine("String Builder took " + stringBuilderTicks + " ticks.");
                Console.WriteLine("Using StringBuilder takes " + ((double)stringBuilderTicks / (double)stringTicks * (double)100).ToString("F") + "% of the time that using String takes.");
    
                //
                // Make the console window stay open
                // so that you can see the results when running from the IDE.
                //
                Console.WriteLine();
                Console.Write("Press any key to finish ... ");
                Console.ReadKey();
            }
        }
    }
    

    Here are the results:

    Concatenation took 5338055 ticks.
    String Builder took 2213 ticks.
    Using StringBuilder takes 0.04% of the time that using String takes.

    Press any key to finish …

Anyway, I hope this post helps you remember the basics.

A WPF front-end for LDPing

I wrote a front-end to LDPing last week-end. You can check it out here:

LDPing

So I was writing a WPF front-end for LDPing, which is a method of querying a LANDesk Agent for its computer name and Inventory Id. There is a button that you click to launch the ping and I couldn’t get the thing to enable…Anyway, I figured it out and posted the resolution here:

Refreshing a button enabled/disabled by RelayCommand.CanExecute()

So here is a screen shot of LDPing.

Don’t interrupt a programmer!

I stumbled this article today.

Holding a Program in One's Head

It was totally funny because some of the comments are what I tell my wife all the time. Here is a quote if you don’t want to read the whole article.

Perhaps it will help if more people understand that the way programmers behave is driven by the demands of the work they do. It’s not because they’re irresponsible that they work in long binges during which they blow off all other obligations, plunge straight into programming instead of writing specs first, and rewrite code that already works. It’s not because they’re unfriendly that they prefer to work alone, or growl at people who pop their head in the door to say hello. This apparently random collection of annoying habits has a single explanation: the power of holding a program in one’s head.

This article also clearly describes problems at see at my job, working on dev in an organization.

So that is why I thought I would share it with my readers as well.

The Atlantic: How I Failed, Failed, and Finally Succeeded at Learning How to Code

I ran across this article and it rang so true to me that I had to share it.

How I Failed, Failed, and Finally Succeeded at Learning How to Code

This article talks about how college’s and schools and drab and can’t teach with excitement, and programming is just exciting when taught correctly.  It is basically saying that programming is best learned by just going at solving a problem and learn as you go.

CSS is a solution for HTML layouts but it is not a good solution

I don’t want to offend any CSS purists out there, but the more I use CSS the more I realize that is isn’t the best tool in the toolbox for layout. I am not saying html tags such as table layouts are better, but I am saying that there were problems that CSS was written to resolve, and as I understand it HTML layouts and page design is one of them, but even after 10 years it is nowhere near where it needs to be in a few areas:

  1. Feature set
  2. Simplicity
  3. Readability is low
  4. Ability to translate functionality into an IDE is poor (as seen by the fact that there is not good CSS IDE)

A while back I found a three column layout and posted about it: https://www.rhyous.com/2011/02/26/the-perfect-layout-for-a-three-column-blog/

At the time, I thought, great someone has figured out all the complexities for me. Well, actually no, they didn’t.  Trying to implement this for a blog design has been a nightmare because I want even more features and adding them to the design has not worked out very well. The design is great, and the author, Matthew James Taylor, should not think that I am trashing his work. No, not at all. He provided an excellent solution. No, instead, I am trashing CSS and its sub-par implementation.

How is it that after so many years and so many versions, CSS is overly complex and the “tricks” such as making  div elements embedded in div elements as Matthew James Taylor used, work but barely and they cause almost as many problems as they solve.

Now I have a problem trying to make the columns on the left and right have rounded corners.  Not going to happen. The way the nested div elements were used to make the background color go all the way down also seems to mean that four rounded corners in each column extending the lengthe of the screen is not likely to happen without more CSS tricks.

I need to add a menu bar, as this layout didn’t have one, but I need the menu bar to also have a drop down menu for submenu items.  However, the way this CSS layout used the div inside div trick, makes the drop down menu below the middle column so that is a problem.

Had I used a table to layout my site, it would be done already. Now, it wouldn’t be the most maintainable but it would be done.  However, maybe a programming language such as PHP or ASP.NET could be used to improve the maintainability.

So to all those who are participating in the CSS standards, please go back to the drawing board when it comes to the layout:

  1. It seems a sub-par job separating the design from the code.
  2. It seems a sub-par job providing an easy tool for laying out a website. You have left us with a tool that is not good enough!
  3. There are not any good IDEs for CSS and HTML (No, neither Dreamweaver or Expression Web are good for laying out web pages, but you know what, it isn’t the fault of the IDE!)

You did solve some of the easy parts quite well, most of the parts that are not “layout” but more just color schemes.

  1. Change font-size and color works great.
  2. Float something to the left, great.

However, a simple feature of “as tall as the page” or the idea of a few elements where all but one are fixed size and the one that isn’t stretches the width of the height of the screen doesn’t exist. It seems to be there for width, but not for height or else it is there but just too hard to get.  For example, look at the three column design.  The reason the author had to nest the div elements was to get the three column div elements to extend all the way to the bottom of the page.  Without this hack, when there are three columns (left, middle, right) normally each one is a different length.  Really, CSS hasn’t solved this with a simple solution, yet? Sorry to be critical, but after this long, it should be better.

Here is what I want it shouldn’t be so difficult.  These tags don’t exist, this is a hypothetical of what I want.  Funny that as I write this some is similar to WPF, which is far superior to CSS for layout design IMHO.

<div name="Header" width="stretch" height="100px"> .... </div>
<div name="Menu" width="stretch" height="sizetocontent> .. </div>
<div name="Columns" width="stretch">
    <Group type="Horizontal" width="stretch">
        <div name="LeftCol" width="250px" hight="stretch"> ... </div>
        <div name="MiddleColCol" width="stretch" hight="stretch" MinWidth="300"> ... </div>
        <div name="LeftCol" width="stretch" hight="stretch"> ... </div>
    </HorizontalGroup>
</div>
<div name="Header" width="stretch" height="100px"> .... </div>

First off, the readability of the above syntax is amazingly clear and simple (IMO) and one does not have to wonder what is intended.

So please, powers that be of CSS, lets start over. Yes, I am aware it could take a decade but it is worth it if this time, you get it right! Look at WPF, sure it is not exactly the same, but Microsoft invested a lot of time and money into Windows Forms and they still felt the need for a new solution in WPF and it has been around 6 years and still Windows Forms are around, but more an more everyone is moving to WPF. CSS should go the way of Windows Forms, and become the old solution that a better solution is designed to replace.

Here are some more articles where people agree that CSS needs to be replaced with a better tool.  Please note as you read these posts that I don’t think CSS sucks.  I think it was a descent tool written to solve a problem, and succeeded in some areas and failed in others, and now that we know what works and what doesn’t a new better tool should be developed that keeps what works in CSS bt also succeeds where CSS fails.

Ten reasons why CSS sucks « Greg’s Head

CSS Sucks (for layout) | Accidental Scientist (this is interesting because Layout is my main complaint)

Tables vs CSS: 15 points to consider when choosing (this one has a lot of links that are not in favor of CSS)

If you are a framer for a house, a hammer is better than a wrench for nailing nails.  But a nail-gun is better than a hammer. CSS is somewhere in between. Here is a good hammer/nail gun analogy to describe CSS. Once I had a nail gun but the air compressor wasn’t quite strong enough and didn’t send the nails all the way in. So I use the nail gun because this was still faster, and did all the nailing. Then I pulled out my hammer and to finish the job.  CSS is like a nail gun without enough air.  It is better than a hammer, but not as good as it could be.

Maybe CSS doesn’t need to go away, maybe it just needs to stop doing layout.  What if it just did size and color and decoration and a new tool integrated with HTML and CSS to do layouts. But maybe it is better to have one solution for design.

How to disable row selection in a WPF DataGrid?

Disabling row selection in the WPF DataGrid included in .NET Framework 4 is not really easy. It is extremely difficult to do, unless you have the right tools and know exactly how to do it.

But all the difficulty is in figuring out how to do it. Once you know how to do it, the steps are quite easy to perform.

First, you basically have to use a copy of the default DataGrid style. However, the easiest way to get a copy of the default DataGrid style is using Expression Blend.

Read more one my new WPF Sharp site here:

How to disable row selection in a WPF DataGrid?

How to create a copy of a control’s default style?

Sometimes you need to make some advanced styling changes to a default control, such as a RadioButton, ListBox, DataGrid, Button, etc. However, you may want to keep the majority of the default style the way it is.

In Expression Blend, this is easy to do. If you don’t have Expression Blend and you are developing in WPF, get it immediately. There is a trial version you can test out.

Here is how to get your copy of any control’s default style….

Read more on my new WPF Sharp site
How to create a copy of a control’s default style?

See my article on Mono in the BSD Magazine May issue

The BSD Magazine has released and there is an article in it by yours truly.

Check it out.

May issue of BSD magazine- Embedded BSD: FreeBSD and Alix

Brigham Young University News: BYU Center for Animation’s new film a double ‘student Emmy’ winner

This is pretty cool. The animation looks as good as anything out there.

BYU Center for Animation’s new film a double ‘student Emmy’ winner

It is good to see a program at my Alma mater doing so well and those involved getting some praise!

C# – The ?? operator or coalesce operator

Here is a little code that returns either x or y. It returns y if x is null, otherwise it returns x.
return (x == null) ? y : x;

The coalesce operator is basically short hand for this. The ?? operator simplifies and shortens the above expression.
return x ?? y;

10 Step process for developing a new WPF application the right way using C#

It makes a difference if you do something the right way from the beginning.  Everything seems to work out so much better and takes less time over all.

Here are some basic steps that I have learned will help you do it right the first time. These steps are from my experience, mostly because I did it wrong the first few times.  These are not exact steps. They are subject to change and improve.  In fact, you might have improvements to suggest immediately when you read this. But if you are new to WPF, then reading these steps before you start and following them, will have you closer it doing it the right way the first time.  It is much more pleasant to tweak a pretty good process than it is to go in with no idea for a process and do it wrong.

Step 1 – Prepare the idea

  1. Some one has an idea
  2. Determine the minimal features for release 1.
  3. Determine the minimal features for release 2.
    1. Alter minimal features for release 1 if it makes sense to do so.
  4. Determine the minimal features for release 3.
    1. Alter minimal features for release 1 and 2 if it makes sense to do so.

Step 2 – Design the Application’s back end business logic (simultaneous to Step 3)

  1. Design the backend
  2. Apply the “Keep it simple” idea to the business logic and makes changes as necessary.
  3. Apply the “Keep it secure” idea to the business logic and makes changes as necessary.
  4. Repeats steps 2 and 3 if necessary.
  5. Backend development can start now as the UI and the back end should not need to know about each other, though this coding is listed as the Step 5 item.

Step 3 – Design the UI using WPF (simultaneous to Step 2)

  1. Determine what development model should be used to separate the UI from the business logic.
    1. Model-View-ViewModel (MVVM) is the model I recommend for WPF.
    2. Gather libraries used for the model (such as common MVVM libraries that include the common ViewModelBase and RelayCommand objects)
  2. Consider using a 3rd party WPF control set will be used.  Many 3rd party companies provide WPF controls that are better and easier to use than those included by default.
    1. If you decided to use 3rd party controls, purchase or otherwise obtain the libraries for these 3rd party controls.
  3. Consider designing two WPF interfaces or skins (I will call these Views from here on out) for each screen. This will help drive the separation of the back end code from the WPF code. Also if developing two Views is not simple, it indicates a poor design.
  4. Design the interface(s) (you may be doing two Views) using SketchFlow (take time to include the libraries for the 3rd party WPF Controls in your SketchFlow project and design with them)
    1. SketchFlow allows you to design the UI, which is commonly done in paint, but instead does this in XAML, and is actually the WPF code your application will use.
  5. SketchFlow allows you to deliver the design (or both Views if you did two) as a package to the customer.
    1. Deliver it immediately and get feedback.
    2. Make changes suggested by the customer if in scope.
  6. Take time to make the XAML in SketchFlow production ready.
  7. Deliver the XAML to the customer again, to buy of that the design changes are proper.
    1. Make changes suggested by the customer if in scope.

Step 4 – Determine the delivery or install method

  1. Determine the delivery method.
  2. Determine when to develop the delivery method.
    1. The easier the application is, the longer you can wait to determine the installer or delivery method.
    2. The more complex the install or delivery method, the sooner this should be started.

Step 5 – Develop the business logic

  1. Develop the application designed in step 2.
  2. Get the application working without UI or silently. Note: Start the next step, Develop the UI, as soon as enough code is available here.

Step 6 – Add Bindings to the UI

  1. Start the UI project by copying the XAML from the SketchFlow document to your Visual Studio or Expression Blend project.
  2. Determine a method for setting the DataContext without linking the View to any ViewModel or Model dlls.
  3. Create a project for the ViewModel code and develop it to interact with the business logic using Binding.
  4. Remember to develop two Views for every UI screen as this will help, though not guarantee, that the the MVVM model was correctly used.

Step 7 – Develop the View Model

  1. You should now have a backend code and a View, and now you start creating the View Model.
  2. This should be in a separate dll than the View or ViewModel.
  3. The ViewModel should never link to the View but can link to Model and Business libraries, though you may consider interface-based design and only link to an interface library.
  4. Make sure to use the properties that the View is binding to.

Step 8 – Consider a other platforms

Macintosh

Macintosh owns a significant market share.  Determine if this application needs to run on Macintosh as well. Sure, since we are running C# your options are limited to either rewriting in objective C and Coca, or using Mono with a MonoMac UI.  I recommend the latter.

Note: It is critical that the UI and business logic are separated to really make this successful.

  1. Completely ignore the WPF design and have Macintosh users users assist the design team in designing the new UI.  Macintosh’s have a different feel, and trying to convert the same UI is a mistake.
  2. Create the MonoMac UI project.
  3. Create a project similar to the ViewModel project in Windows, to link the UI to the business logic.

BSD/Linux/Unix

BLU (BSD/Linux/Unix) doesn’t exactly own a significant market share. However, it is still important to determine if this application needs to run on on BLU as well. Sure, since we are running C# your options are limited to either rewriting in C++, or using Mono with a GTK# or Forms UI.

  1. Completely ignore the WPF and Macintosh designs and have Linux users assist the design team in designing the new UI. Linux have a different feel, and trying to convert the same UI is a mistake.
  2. Create the GTK# project.
  3. Create a project similar to the ViewModel project in Windows, to link the UI to the business logic.
  4. GTK# doesn’t support binding, but still keep the UI separate from the business logic as much as possible.
  5. Also, don’t develop for a single open source flavor, but use standard code that compiles and any BSD/Linux/Unix platform.

Mobile Platforms

  1. Do you need to have this app on IOS or Android or Windows Phone?
  2. Completely ignore the WPF and Macintosh and Linux designs and have Android or IOS users assist the design team in designing the new UI. Mobile platforms have a different feel, and trying to convert the same UI is impossible as the screens are much smaller.

Step 9 – Develop the delivery method

Again, you may need to do this way sooner if the application is complex.

  1. Develop the install or delivery method.
  2. If you decided to deploy to Macintosh or BLU you may have to develop separate install or delivery methods for those platforms as well.
  3. Remember to have a plan and a test for your first patch even if you have to mock a sample patch before you release.
  4. Remember to have a plan and a test for upgrading your application even if you have to mock a sample upgrade version before you release.

Step 10 – Deliver the finished Products

  1. Once finished, deliver this product.
  2. If you decided to create a Macintosh or BLU version, deliver them when ready as well.  It is OK and maybe preferred to deliver these at different times.