Microsoft Visual Studio Installer Projects


I was forced to remain using Visual Studio 2010 and not upgrade to Visual Studio 2012 or Visual Studio 2013, because my company has dozens of internally used utility apps that use visual studio installer/setup projects. It just is not worth the effort to migrate to another installer technology.

Surprising, last year Microsoft reversed the decision to remove set-up projects, as politically the focus was on getting developers making Windows Store applications where the end product is submitted to Microsoft to host and manage. I write this post as I still come across developers that are unaware that this functionality has been returned.

You can download the extension package from here that updates Visual Studio 2013 only (not Visual Studio 2012)

Setup

After installing the extension you will see the project template available in Visual Studio 2013 shown below

Installer/Setup project

I am currently evaluating Visual Studio 2015 preview, so one naturally assumed that you would be able to create a new set-up project as the functionality had been returned in the previous version, albeit via an add-in extension, I assumed I could see the project template shown in the image above, but it was not there.

It turns out that Microsoft have changed their mind again, and decided not to include installer/setup project in Visual Studio 2015, article available here.

We’d like to thank you all for your comments on this UserVoice entry. We have been discussing the comments on InstallShield Limited Edition (ISLE) raised here with Flexera and we are currently working with them to address the top issues. At this stage we have no plans to include the former Visual Studio Setup Projects in future product versions but we will continue to work with Flexera and the community to ensure Visual Studio customers’ setup needs will be met with no-cost tooling that supports a broad range of scenarios.

Tony Goodhew, Program Manager, VS Pro.

 This is a very frustrating development, a decision based on political and not technical issues. it just means a whole class of Visual Studio developer simply won’t upgrade.

Writing multithreaded programs using Async & Await in C#


The biggest feature in C# and Visual Basic languages in Visual Studio 11 is inclusion of first class language support for asynchrony. Writing multi-threaded programs that scale, are easily modifiable, maintainable and understandable by more than one person (i.e. the one that wrote the code) is hard. This is certainly something I have seen people get wrong time and time again.

Probably the most dangerous word to use with undergraduate or even postgraduates is the word “Thread”. When developing software systems, this is certainly an area that requires somebody experienced, and proactive enough to ensure that developers are monitored when they are assigned tasks using threading, as things can get out of hand very quickly.. I have always tried to ensure that developers refrain from using the Thread class and suggesting they use the ThreadPool  and its QueueUserWorkItem  method or the background worker component where possible, but there are times when you have to implement the IAsyncResult design pattern, which makes understanding what your normally synchronous application (and mind-set) hard, because there is an Inversion of Control in the code that is executing, requiring you use a WaitCallBack and WaitHandles and ManualResetEvent and AutoResetEvent classes.

As we move forward, it is more important that developers are as productive as possible, especially in a world where devices are proliferating at the rate that they are. I can now program a Computer, Mobile Phone or Tablet, where connectivity, and updating is a real issue on tablets and phones, so being able to write robust, multi-threaded code quickly and relatively bug free increases in importance.

Note that I am using WPF in this example, if you would like to know how to do this in WinRT/Metro, then have a look at this example.

Single Threaded Example

If you run Visual Studio and create a new WPF application and call the project AsyncWpfApplication

NewProject

This synchronous application application is going to process a list of URLs, and calculate the size of the pages so please ensure you add a reference to System.Net.Http

SystemNet

Add the following XAML markup

<Window x:Class="AsyncWpfApplication.MainWindow"
Title="MainWindow" Height="400" Width="600">
<Grid>
 
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
 
<TextBox Margin="20" Grid.Row="0" HorizontalAlignment="Left" TextWrapping="Wrap" FontFamily="Lucida Console" x:Name="resultsTextBox" Height="250" Width="500" />
<Button Grid.Row="1" HorizontalAlignment="Right" Margin="0,0,70,20" Content="Start" x:Name="startButton" Height="22" Width="75" Click="startButton_Click_1" />
 
</Grid>
</Window>
 

Add the following in the code behind

using System;
using System.Collections.Generic;
using System.Windows;
using System.Net.Http;
using System.Net;
using System.IO;
using System.Threading.Tasks;
 
namespace AsyncWpfApplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
 
private void startButton_Click_1(object sender, RoutedEventArgs e)
{
resultsTextBox.Clear();
SumPageSizes();
resultsTextBox.Text += "\r\nControl returned to startButton_Click.";
}
 
private void SumPageSizes()
{
// Make a list of web addresses.
IEnumerable<string> urlList = SetUpURLList();
 
var total = 0;
foreach (var url in urlList)
{
// GetURLContents returns the contents of url as a byte array.
byte[] urlContents = GetURLContents(url);
 
DisplayResults(url, urlContents);
 
// Update the total.
total += urlContents.Length;
}
 
// Display the total count for all of the web addresses.
resultsTextBox.Text += string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
}
 
 
private IEnumerable<string> SetUpURLList()
{
var urls = new List<string>
{
};
return urls;
}
 
 
private byte[] GetURLContents(string url)
{
// The downloaded resource ends up in the variable named content.
var content = new MemoryStream();
 
// Initialize an HttpWebRequest for the current URL.
var webReq = (HttpWebRequest)WebRequest.Create(url);
 
// Send the request to the Internet resource and wait for
// the response.
using (var response = webReq.GetResponse())
{
// Get the data stream that is associated with the specified URL.
using (Stream responseStream = response.GetResponseStream())
{
// Read the bytes in responseStream and copy them to content. 
responseStream.CopyTo(content);
}
}
 
// Return the result as a byte array.
return content.ToArray();
}
 
private void DisplayResults(string url, byte[] content)
{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "http://&quot;.
var displayURL = url.Replace("http://&quot;, "");
resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
}
}
}
 

If you then hit F5 to run the application and press start you will find that the start button sticks and the application itself is unresponsive because of all the work that is blocking the main UI thread. After a few moment you should get the following

Screen

Multithreaded Example

When retrofitting the new asyc language features you need to be aware of the following

  1. The new asyc language capabilities are based around Task<T> found in System.Threading.Tasks.Task<TResult>. Knowing how that class works with increase the ease of you ability to use the new asyc features
  2. Any method that uses the new asynchronous functionality must use the new keyword asyc.
  3. There are a plethora of new classes in the .NET framework that are suffixed with Asyc that return a Task<T> that you can use with the new await keyword.
using System;
using System.Collections.Generic;
using System.Windows;
using System.Net.Http;
using System.Net;
using System.IO;
using System.Threading.Tasks;
 
namespace AsyncWpfApplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
 
private async void startButton_Click_1(object sender, RoutedEventArgs e)
{
resultsTextBox.Clear();
await SumPageSizesAsync();
resultsTextBox.Text += "\r\nControl returned to startButton_Click.";
}
 
private async Task SumPageSizesAsync()
{
// Make a list of web addresses.
IEnumerable<string> urlList = SetUpURLList();
 
var total = 0;
 
foreach (var url in urlList)
{
// GetURLContentsAsync returns a Task<T>. At completion, the task
// produces a byte array.
Task<byte[]> getContentsTask = GetURLContentsAsync(url);
byte[] urlContents = await getContentsTask;
 
// The following line can replace the previous two assignment statements.
//byte[] urlContents = await GetURLContentsAsync(url);
 
DisplayResults(url, urlContents);
 
// Update the total.         
total += urlContents.Length;
}
 
// Display the total count for all of the websites.
resultsTextBox.Text +=
string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
}
 
 
 
 
private IEnumerable<string> SetUpURLList()
{
var urls = new List<string>
{
};
return urls;
}
 
private async Task<byte[]> GetURLContentsAsync(string url)
{
// The downloaded resource ends up in the variable named content.
var content = new MemoryStream();
 
// Initialize an HttpWebRequest for the current URL.
var webReq = (HttpWebRequest)WebRequest.Create(url);
 
// Send the request to the Internet resource and wait for
// the response.
Task<WebResponse> responseTask = webReq.GetResponseAsync();
using (WebResponse response = await responseTask)
{
// The following line can replace the previous two lines.
//using (WebResponse response = await webReq.GetResponseAsync())
 
// Get the data stream that is associated with the specified url.
using (Stream responseStream = response.GetResponseStream())
{
// Read the bytes in responseStream and copy them to content.
// CopyToAsync returns a Task, not a Task<T>.
Task copyTask = responseStream.CopyToAsync(content);
 
// When copyTask is completed, content contains a copy of
// responseStream.
await copyTask;
 
// The following line can replace the previous two statements.
//await responseStream.CopyToAsync(content);
}
}
 
// Return the result as a byte array.
return content.ToArray();
}
 
 
 
private void DisplayResults(string url, byte[] content)
{
// Display the length of each website. The string format
// is designed to be used with a monospaced font, such as
// Lucida Console or Global Monospace.
var bytes = content.Length;
// Strip off the "http://&quot;.
var displayURL = url.Replace("http://&quot;, "");
resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
}
}
}

    If you examine the retrofitted example above you will see that the synchronous methods have indeed been replaced with their methods that are suffixed with Async e.g. SomeMethodAsyc and all you have to do is use the await keyword until the asynchronous task completes. The C# language team have really made asynchronous programming “easy peasy lemon squeezy”.

Get directory of an executing assembly in C# and Visual Basic


Continuing my series of short but useful tips and tricks, one usually needs to find the directory of an executing assembly. The simple console application below shows how to do this. The Visual Basic example is after the C# one.

C#

using System;
using System.IO;
using System.Reflection;
 
namespace ConsoleApplication2
{
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Directory: " + AssemblyDirectory());
Console.WriteLine("Location: " + Assembly.GetExecutingAssembly().Location);
Console.ReadKey();
}
 
public static string AssemblyDirectory()
{
var uri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase);
return Path.GetDirectoryName(Uri.UnescapeDataString(uri.Path));
}
 
}
}
 

Visual Basic

 

Imports System.Reflection
Imports System.IO
 
Module Module1
 
Sub Main()
Console.WriteLine("Directory: " + AssemblyDirectory())
Console.WriteLine("Location: " + Assembly.GetExecutingAssembly().Location)
Console.ReadKey()
End Sub
 
Public Function AssemblyDirectory() As String
Dim uri = New UriBuilder(Assembly.GetExecutingAssembly().CodeBase)
Return Path.GetDirectoryName(System.Uri.UnescapeDataString(uri.Path))
End Function
 
End Module

Single instance WPF application in C#


Update: 12/03/2012

I ran into some issues with the approach that I linked to below, and would not recommend it. It turns out that the best way to deal with this issue, is to use the Visual Basic instance detection classes (yes you can use these from C#). The sample code is available here

Note that is is more than likely that you will be retrofitting this to an existing project. If that is the case, make sure you double click the properties pane in visual studio and set your custom start-up file/class as shown below

startup

 

Original Post

Keeping in the same vein as my previous post, I frequently find that I have to solve the same problems at times. After a year or several months I usually move onto another project, consequently no longer have the source code, so I am posting this as a bit of a sticky as I am sure someone will find it useful.

Visual Basic has single instance classes one can use, one can import these into any C# application and consume them (that, after all,  is the real beauty of .NET), but I found that there was too much code, and too many classes, and it was taking me too long a little while back. I solve this problem using the Process class. Create a WPF application and use as follows;

using System.Diagnostics;
using System.Linq;
using System.Windows;
 
namespace SingleInstanceApp
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
IsAppAlreadyRunning();
}
 
private static void IsAppAlreadyRunning()
{
Process currentProcess = Process.GetCurrentProcess();
 
if (Process.GetProcessesByName(currentProcess.ProcessName).Any(p => p.Id != currentProcess.Id))
{
MessageBox.Show("Another instance is already running.", "Application already running",
MessageBoxButton.OK, MessageBoxImage.Exclamation);
Current.Shutdown();
return;
}
}
}
}

Copying an object in C# and Visual Basic


Sometimes there are classes you find you use in every project. I remember once (shudder) I, rather inelegantly instantiated a class, and performed a manual copy of all the properties in the object (when the pressure was on, and I just needed to make the thing work).

I have also found myself spending hours chasing subtle and hard to debug issues where ICloneable has been used -  which, incidentally, is widely accepted as an interface one ought never use – or Object.MemberwiseClone. It turns out the only way to do this correctly, is to serialise the object, and then use the deserialised object, implemented here using an extension method.

Even though this is quite straightforward, I still am posting this however , because I find I need to use this functionality frequently, and often I no longer have access to the source, or it takes ages to find the class. The Visual Basic code sample is after the C# one.

C#

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
 
namespace ObjectCopierApp.Extensions
{
/// <summary>
/// Provides a method for performing deep copying of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>
internal static class ObjectCopier
{
/// <summary>
/// Perform a deep copy of an object.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
internal static T Clone<T>(this T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
 
// Don’t serialize a null object, simply return the default for that object
if (ReferenceEquals(source, null))
{
return default(T);
}
 
IFormatter formatter = new BinaryFormatter();
 
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
}
}
 
 

Visual Basic

Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
 
Namespace ObjectCopierApp.Extensions
”’ <summary>
”’ Provides a method for performing deep copying of an object.
”’ Binary Serialization is used to perform the copy.
”’ </summary>
Friend NotInheritable Class ObjectCopier
Private Sub New()
End Sub
”’ <summary>
”’ Perform a deep copy of an object.
”’ </summary>
”’ <typeparam name="T">The type of object being copied.</typeparam>
”’ <param name="source">The object instance to copy.</param>
”’ <returns>The copied object.</returns>
<System.Runtime.CompilerServices.Extension()> _
Friend Shared Function Clone(Of T)(source As T) As T
If Not GetType(T).IsSerializable Then
Throw New ArgumentException("The type must be serializable.", "source")
End If
 
‘ Don’t serialize a null object, simply return the default for that object
If ReferenceEquals(source, Nothing) Then
Return Nothing
End If
 
Dim formatter As IFormatter = New BinaryFormatter()
 
Using stream = New MemoryStream()
formatter.Serialize(stream, source)
stream.Seek(0, SeekOrigin.Begin)
Return DirectCast(formatter.Deserialize(stream), T)
End Using
End Function
End Class
End Namespace

ItemsControl Performance Improvements in .NET 4.5


WPF is Slow

One of the most common complaints from C++ or Windows Forms developers moving to WPF/XAML is the issue of performance. I have worked exclusively and intricately with WPF/XAML for the last 4 years and at times have come across performance issues that put me in a corner, including;

  • I needed to enumerate all the alarm and safety devices in an Airports security system inventory. This included fire, smoke, travelator, escalator, motion detection etc. in effect I needed to load up thousands of hardware devices into the WPF application for configuration
  • I was dealing with scientific data for DNA, RNA and Protein. Typically you would have an image with an electropherogram attached to it, which contains thousands of points of floating point data. Scientists required the ability to step through several different samples quickly in order to perform analysis on this data.
    In both these applications, I ended up having to make significant compromises, including using a Windows Forms chart in the scientific application as loading thousands of floating point data into the plethora of commercial and open source WPF charts we tried was unbearably slow. The Windows Forms chart would render the data in milliseconds, where WPF would take a minimum of 10 or 20 seconds with the same data-set, and given the fact that we needed to extend the chart with additional functionality, it added several months worth of development to alter the Windows Forms chart, where it would have been far easier and less time consuming using WPF.

    Staggering

    It turns out that peoples cries about the sluggish nature of WPF applications are correct. Microsoft have managed to attain simply staggering performance improvements to the ItemsControl in WPF. An ItemsControl represents a control that can be used to present a collection of items. In WPF, this includes the TreeView, ListBox, ListView and DataGrid controls that are built using ItemsControls.

DotNet4

In .NET 4 (Visual Studio 2010) and previous, a test was conducted where 12 000 items are loaded into an ItemsControl, the results are in the image below

OutOfMemory

After about 7 minutes, the computer throws an out of memory exception, which I am sure you will agree is absolutely terrible. Microsoft prioritised this issue and in the first iteration managed to increase the total number of items loaded to 200 000 (from 12 000) and load these in 24.5 seconds, an incredible improvement.

FirstIteration

The Pièce de résistance is that they continued to try and get this already considerable metric down even further, in the end  they got this down to 2.3 seconds.

Final

If you have a WPF application that is data centric, especially handling thousands of rows of data, then upgrading to .NET 4.5 is an absolute no brainer. WPF is now at least 182 times quicker whilst handling 16 times more data.

It means that WPF is going to be significantly faster with the additional improvements that have been made to virtualisation in ItemsControls and Cold/Warm start-up times for .NET applications in general.

Calculate range/limit with C#


A recurring requirement in every day programming is determining whether a value exists with a certain range. Since it is exam time (for most students at present), I resolved to write a quick application demonstrating this requirement based around examination marks.

This quick demo is written in WPF, but should work in Silverlight or Windows Phone 7 with no alteration. The Range class though, can be used throughout .NET in general.

To start with, create a new WPF application in visual Studio and call it ExamApp. Add a new folder to the project called Range and in this declare a new interface called IRange with the following members

using System;
 
namespace ExamApp.Range
{
public interface IRange<T> where T : IComparable<T>
{
T Start { get; }
T End { get; }
bool InRange(T valueToFind);
}
}

Create a new class in the same folder called Range which implements the interface above

using System;
 
namespace ExamApp.Range
{
public class Range<T> : IRange<T> where T : IComparable<T>
{
private readonly T start;
private readonly T end;
 
public Range(T start, T end)
{
if (start.CompareTo(end) <= 0)
{
this.start = start;
this.end = end;
}
else
{
this.start = end;
this.end = start;
}
}
 
public T Start
{
get { return this.start; }
}
 
public T End
{
get { return this.end; }
}
 
public bool InRange(T valueToFind)
{
return valueToFind.CompareTo(Start) >= 0 && valueToFind.CompareTo(End) <= 0;
}
}
}
 

Add a new Folder to the project called Examinations and in this add a new class called Percentage. This Percentage class inherits off Range, and here you can create whatever logical range class you may desire for your own applications

using System;

using ExamApp.Range;
 
namespace ExamApp.Examinations
{
public class Percentage<T> : Range<T> where T : IComparable<T>
{
public Percentage(T start, T end) : base(start, end)
{
}
}
}
 

Add a new enumeration called Grade thus

namespace ExamApp.Examinations

{
public enum Grade
{
None = 0,
A = 1,
B = 2,
C = 3,
D = 4,
E = 5,
} ;
}
 

Add a new interface called ITest with the following members.

namespace ExamApp.Examinations

{
interface ITest
{
int ArtAndDesignMark { get; set; }
int ScienceMark { get; set; }
int MathsMark { get; set; }
}
}
 

Add a new folder called Converters to the project, and add the following

using System;

using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows.Data;
using System.Windows.Markup;
using ExamApp.Examinations;
 
namespace ExamApp.Converters
{
public class MarkToGradeConverter : MarkupExtension, IValueConverter
{
private static MarkToGradeConverter instance;
private static readonly Dictionary<Percentage<int>, Grade> Marks;
 
static MarkToGradeConverter()
{
Marks = new Dictionary<Percentage<int>, Grade>
{
{new Percentage<int>(80, 100), Grade.A},
{new Percentage<int>(75, 79), Grade.B},
{new Percentage<int>(60, 74), Grade.C},
{new Percentage<int>(55, 59), Grade.D},
{new Percentage<int>(0, 54), Grade.E},
};
}
 
public override object ProvideValue(IServiceProvider serviceProvider)
{
return instance ?? (instance = new MarkToGradeConverter());
}
 
#region Implementation of IValueConverter
 
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return GetGrade((int)value).ToString();
}
 
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
 
public static Grade GetGrade(int mark)
{
Percentage<int> key = Marks.Keys.FirstOrDefault(r => r.InRange(mark));
 
if (key != null)
{
Grade grade;
 
if (Marks.TryGetValue(key, out grade))
{
return grade;
}
}
return Grade.None;
}
 
#endregion
}
}
 

As you can see most of the logic is executed here. Add a new class to the project called Student with the following properties. Also note that this implements the ITest interface that was declared earlier

using ExamApp.Examinations;

 
namespace ExamApp
{
public class Student : ITest
{
public Student(string firstName, string surname, int artAndDesignMark, int scienceMark, int mathsMark)
{
this.FirstName = firstName;
this.Surname = surname;
this.ArtAndDesignMark = artAndDesignMark;
this.ScienceMark = scienceMark;
this.MathsMark = mathsMark;
}
 
public Student()
{
}
 
public string FirstName { get; set; }
public string Surname { get; set; }
 
#region Implementation of ITest
 
public int ArtAndDesignMark { get; set; }
public int ScienceMark { get; set; }
public int MathsMark { get; set; }
 
#endregion
 
}
}
 

We need a collection of students to show in a list so create the following class that inherits off ObservableCollection<T>

using System.Collections.ObjectModel;

namespace ExamApp
{
public class Students : ObservableCollection<Student>
{
public Students()
{
Add(new Student
{
FirstName = "John",
Surname = "Lennon",
ArtAndDesignMark = 81,
ScienceMark = 59,
MathsMark = 77
});
Add(new Student
{
FirstName = "Paul",
Surname = "McCartney",
ArtAndDesignMark = 88,
ScienceMark = 40,
MathsMark = 66
});
Add(new Student
{
FirstName = "Ringo",
Surname = "Starr",
ArtAndDesignMark = 88,
ScienceMark = 31,
MathsMark = 96
});
Add(new Student
{
FirstName = "George",
Surname = "Harrison",
ArtAndDesignMark = 100,
ScienceMark = 99,
MathsMark = 99
});
 
}
}
}
 

Now the data structures are complete, add the following .xaml markup

<Window x:Class="ExamApp.MainWindow"
xmlns:Converters="clr-namespace:ExamApp.Converters"
Title="MainWindow"
Width="525"
Height="350">
<Window.Resources>
<Converters:MarkToGradeConverter x:Key="MarkToGradeConverter" />
</Window.Resources>
<ListView x:Name="studentsListBox">
<ListView.View>
<GridView>
<GridViewColumn Width="120"
DisplayMemberBinding="{Binding Path=FirstName}"
Header="Name" />
<GridViewColumn Width="120"
DisplayMemberBinding="{Binding Path=Surname}"
Header="Surname" />
<GridViewColumn Width="40"
DisplayMemberBinding="{Binding Path=ArtAndDesignMark,
Converter={StaticResource MarkToGradeConverter}}"
Header="Art" />
<GridViewColumn Width="60"
DisplayMemberBinding="{Binding Path=ScienceMark,
Converter={StaticResource MarkToGradeConverter}}"
Header="Science" />
<GridViewColumn Width="50"
DisplayMemberBinding="{Binding Path=MathsMark,
Converter={StaticResource MarkToGradeConverter}}"
Header="Maths" />
</GridView>
</ListView.View>
 
</ListView>
 
</Window>
 

Add the following code to the constructor of the main window

using System.Windows;
 
namespace ExamApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.studentsListBox.ItemsSource = new Students();
}
}
}
 

You should have the following

Students

As you can see it is quite a simple and pretty reusable way to use ranges in your application.

The source code for this simple example is available here

Reinventing the wheel


One of  the most significant challenges as a developer – especially when working as a consultant (though not mutually exclusive) -  is the need to understand a completely alien software system very very quickly, and to be productive in adding new functionality to that system, consequently value, to whatever the project may be. One must cultivate procedures and practices that allow for the rapid addition of development requests that are fit for purpose.

Probably the biggest hindrance in all software development is developers that suffer from “not invented here, I didn’t write it” syndrome. Frequently, I encounter developers that cannot work on a piece of code without completely re-writing it, frequently either ending up with exactly the same functionality as the code they replaced or reinventing a square wheel i.e. one finds that one is actually are worse off from a code maintainability standpoint.

The role of any Software Architect or Team Lead, is primarily to ensure that the overall architecture of  a software system is sound i.e. well designed and robust, lending itself to the addition of new functionality without breaking or changing existing code. This is by no means easy, and the challenges of building software systems are well known, but software architecture is now no longer in the dark ages, established design patterns that resolve most system issues are abundantly available. This most important part of any software application, I cannot but help but to draw attention to that fact, getting this wrong, with the knowledge that you will have developers of varying abilities and skills during the lifetime of the application, is all but a recipe for failure.

Design

The architecture of the application must be a policy and this must be enforced. The architecture must make it difficult for developers to just do what they want by requiring that they have to either take a few extra steps in their algorithm or think differently (but the same for everyone else) in resolving whatever they are tasked with. This however, must be a justified design decision, and not loose coupling just for the sake of loose coupling i.e.using interfaces between layers for example, usually forces composability from developers where they would usually use direct call backs. I have seen systems quickly turn into big balls of mud because of this, and the larger the system that bigger the ball of mud.

 

7299iuz6qug2mn

Since the overall architecture has been formalised, what remains is in adding the functionality of different rooms. The Drawing Room in the home above, must have all the features and components that allow it to function as such. This is analogous to any feature in a software system. It is difficult for your typical programmer to see a software system in its completeness like the house above, so it is the Architects responsibility to ensure they are aware of what is required of them. Most developers don’t like being restricted in how they are allowed to solve a problem, because most developers are not Architects, and are seldom able to design a coherent and robust system. Rewriting code someone else has written for the most part is usually an exercise in absolute futility. One cannot count the times that programmers habitually duplicate functionally that already exists, and how negatively this impacts a projects progression. It is very easy to lose weeks and even months of development time, all because developers were unable to augment existing code that was already working.

Sawdust

If you task a typical programmer to design and develop a piece of functionality in an application, that has specific functionality, the results are often surprising. Requirements for software usually result in a single piece of functionality, lets take a chair for example.

11151bguz98uw24

I am certain the audience knows what the prime functionality of a chair is so I shall not elaborate, why should software be different? The objective for any programmer is to get the requirements realised in as short a time, but as functional as possible. Most programmers never create a chair that is simple and functional but end up with this.

9481t87166dxi7

Really skilled developers will give you something like a Futon

product_detailed_image_29785_21

Most developers spend and incredible amount of time creating sawdust, separating logic and creating loosely coupled components when a lot of the time this is not required. Developers often try and use their glass ball imagining future use cases and try to always create components that can be extended to have dual or many other uses e.g. the Futon above. This is wrong! Oftentimes, all you want is a chair. All the requirements in the software specification ask for is a chair and the developer ended up creating a Futon, then are perplexed when they receive lukewarm responses or even complaints that they have designed something that was not required.

Single responsibility is frequently misunderstood, and is a prime reason that programmers rewrite existing code a lot . Usually the argument is that “I had to split the code into this class, and that class, and the other class because I wanted to create a software component where single responsibility was as clear as possible”. The result almost always is sawdust, and fine grained sawdust at that, because well architected software systems usually just need software components like the chair. It is sometimes hard for intelligent developers to accept that a lot of the code they write at times can be solved very simply, their overactive minds end up creating a software system that is bloated with classes and code that will never ever be used because you aren’t going to need it.

The Graduate

It seems almost unfair to include graduates as prime candidates for reinventing wheels, but they almost always are the people that do this the most, including Masters up to and including PhD students.

21585e5556z58a1

In any software team, you need bright and talented individuals, especially where you are solving domain specific problems. Their importance cannot be overstated here, but with this comes a lot of baggage. It can be very challenging managing a team of incredibly gifted developers. Inexperienced developers of any academic background can also be a drain in resources. A simple problem is usually solved by using the most complex algorithm, when something simpler was required. It seems inconceivable, but most of the hardest problems to manage in complex software systems are usually a result of the smartest people in a teams undue influence. If people are very smart they are hardly ever questioned to justify their choices. I have encountered software where you are told that users hate using the application because “you require a PhD to use the software”. This complexity invariably stems from the source code, thus, it is important to accept that smart individuals always find ways of solving the most difficult problems, but can also be the reason why some problems in complex software systems are difficult to solve because simplicity is seldom a prerequisite in resolving issues.

The long-and-the-short-of-it is that the goal of any software is for people to use it, and most success is based on simplicity and easy of use, which also is true for maintainable software systems. Working software seldom needs to be completely re-written because it works. Improvements can always be made to any software because there are no perfect software systems, so save yourself the time and effort by learning other peoples code rather than rewriting it, this will allow you to solve more problems, add more features and provide real value to a project.

Significant figures bug in C# and .NET in general


Presently, I am working on a scientific application, and have been creating some data tables. A request was made to me to ensure that some data columns be rounded to 3 significant figures e.g.

10.1234 becomes 10.1

10.7335 becomes 10.7

1.1003 becomes 1.10

I thought through this request with nonchalance at first, but was surprised just how difficult and time consuming it turned out to be to fulfil. After trying out many examples on the interwebs, including some lengthy code libraries, the solution was simplicity itself, using the .NET string format modifier G0 where the number after G is the number of significant figures desired,  so

Console.WriteLine((10.12345).ToString(“G3”));

Will give you a result of 10.1

This works fine and as expected, but the bug is when you have 10.0, what is output to screen is 10

After traipsing through numerous articles, the result was that this behaviour was “by design”. After communicating this “by design” feature to my boss (and numerous scientists), their retort was that it was a bug and ought to be corrected. The reason why they were so annoyed was because the missing trailing zero indicates a level of accuracy that is an unacceptable omission in their field, thus I was advised to prefer two decimal places instead.

One of the first rules you are taught as a new programmer, is that numbers in computer programs are zero based i.e. you start counting at zero because zero is a number, so why in this case are the .NET framework designers ignoring the zero? One must say that one concurs with this being a bug, and wish the framework library team could correct this behaviour, to save developers polluting their codebases with conversions to strings and back to numbers, just so one can present data in a way that is meaningful to mathematically based users.

Should I use DevExpress WPF controls for a new project?


Firstly, I must draw attention to the fact that my intention is not to spew bile, or communicate zealot-ism of any shape or form. My intention is to try and provide a fair, concise and balanced view, relative to personal experience that may hopefully assist anyone looking to answer this question.

Presently, I am now nearly six months into a Greenfield project, written exclusively using DevExpress WPF controls. Over the last few months, I have come to know their WPF API’s particularly well, and will continue to use the controls for the lifetime of the project simply because it is too late. A definite consideration is that it is often impossible to change anything major as a third party software suite you are developing on top of midway, for all sorts of reasons, the most notable being expense and time/delay to finish. WPF is such a flexible platform, I would advocate getting the business logic and functionality of an application thrashed out first, then look to a design team or third-party suite right at the end the end or during the process, rather than automatically restricting oneself from the offset with a third party suite. This, however, is seldom practicable, as the product owner/customer will need to be interacting with the software as time progresses, and they want to see something pretty, there is hardly ever any flexibility here, the application has to look stunning very soon into the start of the project, in order to gain their confidence (and settle their nerves) and continue in this vein.

There is nothing like hindsight, a trite but often unavoidable word when reflecting on a projects progression, It is always harder to be objective at a later date, because quite often, a quite different set of circumstances and considerations result due to the fact that time has moved on, and better ways of dealing with technical challenges and vendors present themselves. the steps required to solve particular problems become perspicacious.

One also must accept that projects must commence at some point, and utilise the best that is available at the time, otherwise no-one would ever start anything, because a better suite of components are just around the corner. Invariably, there have been profuse technical challenges along the way, as the application is a scientific one, but that is the essential stimulus for me personally,  yes, not fun some days, and you have good days and bad ones, but the overwhelming sense of achievement in surmounting the obstacles are what makes one do it again and again. Attention to minute detail is of unparalleled importance.  For all intents and purposes, it is about minutiae!

I think it important to take note that this is not a typical forms over data application but of a scientific bent, and thus far, their controls have proven very hard, if not impossible to customise to meet our technical requirements and specifications with ease and eloquence. Over the last month or so, I have been writing code that I quite frankly feel embarrassed to ever admit that I checked in…why?

The biggest problem is that DevExpress developers completely misunderstood WPF when they developed their WPF controls. I really cannot impress upon you sufficiently well just how much of a displeasure it is using their controls. I feel absolutely terrible (almost guilty) about talking about a vendor with such negativity, but they have made a serious mistake in their WPF suite, it has been a singular source of the most abject frustration for me in about a decade of developing software. WPF was built to allow developers to be flexible, and to build components with ease, using DevExpress controls cuts your flexibility by about 90% (and that is not a guesstimate).

Frequently, it is possible to get off to a bad start in any project, even with experienced developers. It is the fresh ideas and perspicacious vision that allow younger developers for the most part to escape the nebulous approach experienced developers tend to exhibit. In my experience developing WPF applications over the last three years or so, one of the most poisonous components to introduce to a new  WPF application, is a dyed-in- the-wool Windows Forms developer. One feels however that one must communicate extensive and comprehensive experience as a Windows Forms developer, but  somehow I managed to shake off any misdirection in solving WPF problems after witnessing just how bad approaching WPF from a C++ and Windows Forms mentality is. On some projects, I have witnessed resplendent software engineers and architects commit the gravest mistakes in implementing WPF projects, simply because they could not and would not start looking at things from a different direction. It is this scourge that has been eminent in the procurement for DevExpress WPF controls, that much is irrefutable.

Recently, after speaking with a colleague, we arrived at the conclusion that their WPF API’s have been written top down by Windows Forms developers. It is that, and their overwhelming success as Third Party Windows Forms Vendors where things have gone horribly wrong. Using their controls in most instances, places asphyxia on whatever problem you are trying to resolve, because most of their API’s are just so hard to get to do what you want them to do, because they failed to grasp what WPF developers expect in their components. Frequently, I consult my rather extensive library of code to solve problems that I find cropping up again and again, but it is almost impossible to use any of my  existing WPF code with their controls, because of the way they have implemented their API’s. That is a sad indictment of the API’s. A simple application that you write in WPF and bind to in an items control or List Box in WPF, is impossible to migrate to their Grid controls for example because of their horrendous implementation.

One of the key components in every WPF project that I have worked on is Model View View-Model (MVVM) proficiency. This has been an essential and sought after skill when dealing with customers. As I write today, you will find plethoric requests for MVVM support for their WPF controls, and hitherto there is none. There are no code samples or examples on their numerous websites, so typically you will confront a problem, and find that their controls are specifically written to handle events in the code-behind and not commands. You will also find that they adore the decade old version of ADO.NET that is datasets. I have not worked on a single WPF application that has not used MVVM or POCO’s, finding anything in their documentation or code samples using POCO’s is as likely as finding a hen with teeth, speaks French, and tells jokes.

Their WPF Ribbon is a prime example of being a complete dog to work with. It is incomplete, non-MVVM compliant, and when customers say their want an Office 2010 Application Menu for example, your sat left wondering, why you paid the money for the controls. Using it in your applications is a factory for writing tightly coupled hard to modify code, and if you do create workarounds you find that you have a polluted codebase, trying to get a MVVM application that is easily testable. Whilst we are on the subject of testing, try to find a single example of a WPF component of theirs in a test situation, I will save you the time, and regrettably advise you that there are no code samples, nor do their components help one build testable code. DevExpress almost obstinately choose to ensure that you develop the hardest to maintain and poorly separated code, by creating components that cultivate bad practices. If you are a design oriented software team or company, you will find that DevExpress only supply asphyxiation to your ability to progress, you can take out the ”express” and replace it with “Dev-Stress” or “Dev-Stressed”

What I cannot however fault, is their support, this is certainly a redeeming feature, because their have an absolutely brilliant support system, and their staff are a joy to work with. They almost always find a solution for a query, though sometimes one is left wondering why  you needed to consult someone to perform what are mostly basic functions.If you are thinking of using their controls then you must be prepared to accept that you are for the most part, a paying guinea pig, because most of the issues you will have have either been reported by other customers, or your problem will be used to resolve other peoples problems in the future, as their websites and forums are pretty useless, they seem to take little care in preparing helpful documentation and code samples that reflect real world usage for their customers, pretty much every example is an example on how not to write quality software.

Another big issue I have found is with their release cycle. They generally have two big releases every year, and lots of incremental ones. If you find a bug, it is always tempting to update to their bug fix versions, but I have found this to be an endless source of hair-loss. Pretty much every time I have upgraded to solve an issue, it has been partially fixed, or ended up creating bugs or their have renamed and changed things that break things. The Visual Studio way of releasing software seems the best for developing complex projects, where over the period of a year or so, you can concentrate of solving the domain problems, rather than bug-riddled releases. It may sound as If I am being harsh or truculent, but this is the reality of using their software.

If you are thinking of using DevExpress WPF controls, you really have to try and assess whether you fall into their 90% use case, or their 10% oddities, but even if you do fall into their 90%, their API’s will assist you in writing a lot of hard to test, inelegant and expensive to maintain code, as they have been written to work best using the paradigm of the technology they are meant to be replacing (Windows Forms). If you have worked with WPF for any amount of time, it is almost unbelievable just how restrictive their controls are to use. Presently, even as one writes, befuddlement  continues to present itself, as to how or why their controls work the way they do? The Microsoft WPF control library is such a flexible system, why asphyxiate you and your organisations software development efforts by people that still write software components as if it was a decade ago?