.NET Framework 4.5

Microsoft is continuing to improve and advance their .NET Framework. As of today (2012/2/4) the Microsoft .NET Framework version 4.5 is available as a “Developer Preview”. You can download it now, install it, and work with it – just be cognizant that this is not production-ready, at this time.

The most up-to-date information should be on msdn.

Downloading, Installing, and Getting Started

What’s New in version 4.5

Migration Guide


What’s New in 4.5 ?

The new features for the .NET Framework 4.5 relative to the earlier release (4.0) may be divided into these 7 categories. Click on the link in each to drill down to view more detailed information.

  1. .NET for Metro style applications

  2. Core Features and Improvements

  3. Web

  4. Networking

  5. Windows Presentation Foundation (WPF)

  6. Windows Communication Foundation (WCF)

  7. Windows Workflow Foundation (WF)


1. .NET for Metro style applications

Metro style apps are designed for specific form factors and leverage the power of the Windows operating system. A subset of the .NET Framework is available for building Metro style apps for Windows using C# or Visual Basic. This subset is called .NET APIs for Metro style apps. For more information about this subset, see .NET for Metro style apps.


2. Core Features and Improvements

  • Ability to limit how long the regular expression engine will attempt to resolve a regular expression before it times out.

  • Ability to define the culture for an application domain.

  • Console support for Unicode (UTF-16) encoding.

  • Support for versioning of cultural string ordering and comparison data.

  • Better performance when retrieving resources.

  • Zip compression improvements to reduce the size of a compressed file.

  • Ability to customize a reflection context to override default reflection behavior through the CustomReflectionContext class.

  • The Managed Extensibility Framework (MEF) gains support for generic types, a convention-based programming model, and multiple scopes.

  • Asynchronous File Operations that use the new task-based asynchronous features that were added to the C# and Visual Basic languages.


3. Web

The ASP.NET 4.5 Developer Preview includes these new features:

  • Support for new HTML5 form types, like email, tel, url, and search.

  • Support for model binders in Web Forms. These let you bind data controls directly to data-access methods, and automatically convert user input to and from .NET Framework data types.

  • Support for unobtrusive JavaScript in client-side validation scripts.

  • Improved handling of client script through bundling and minification for improved page performance.

  • Integrated encoding routines from the AntiXSS library (previously an external library) to protect from cross-site scripting attacks.

  • Support for WebSockets protocol.

  • Support for reading and writing HTTP requests and responses asynchronously.

  • Support for asynchronous modules and handlers.

  • Support for content distribution network (CDN) fallback in the ScriptManager control.

For more information about these features, see What’s New for ASP.NET 4.5 and Web Development in Visual Studio 11 Developer Preview.

Back to top


4. Networking

The .NET Framework 4.5 Developer Preview provides a new programming interface for HTTP applications. For more information, see the new System.Net.Http and System.Net.Http.Headers namespaces.

Also, the following networking improvements are included in the System.Net, System.Net.Mail, and related namespaces:

  • Improved internationalization and IPv6 support.

  • RFC-compliant URI support.

  • Support for Internationalized Domain Name (IDN) parsing.

  • Support for Email Address Internationalization (EAI).

Back to top


5. Windows Presentation Foundation (WPF)

In the .NET Framework 4.5 Developer Preview, Windows Presentation Foundation (WPF) contains changes and improvements in the following areas:

  • The new Ribbon control, which enables you to implement a ribbon user interface that hosts a Quick Access Toolbar, Application Menu, and tabs.

  • The new INotifyDataErrorInfo interface, which supports synchronous and asynchronous data validation.

  • New features for the VirtualizingPanel and Dispatcher classes.

  • Improved performance when displaying large sets of grouped data, and by accessing collections on non-UI threads.

  • Data binding to static properties, data binding to custom types that implement the ICustomTypeProvider interface, and retrieval of data binding information from a binding expression.

  • Repositioning of data as the values change (live shaping).

  • Better integration between WPF and Win32 user interface components.

  • Ability to check whether the data context for an item container is disconnected.

  • Ability to set the amount of time that should elapse between property changes and data source updates.

  • Improved support for implementing weak event patterns. Also, events can now accept markup extensions.

For more information, see What’s New in WPF Version 4.5 Developer Preview.

Back to top


6. Windows Communication Foundation (WCF)

In the .NET Framework 4.5 Developer Preview, the following features have been added to make it simpler to write and maintain Windows Communication Foundation (WCF) applications:

  • Websockets support to enable true bidirectional communication over ports 80 and 443 with performance characteristics similar to the TCP transport. Two new bindings have been added for this: NetHttpBinding and NetHttpsBinding

  • Simplification of generated configuration files.

  • Support for contract-first development. svcutl.exe3 has a /serviceContract switch allowing you to generate service and data contracts from a WSDL document.

  • Ability to configure ASP.NET compatibility mode more easily.

  • Changes in default transport property values to reduce the likelihood that you will have to set them.

  • Updates to the XmlDictionaryReaderQuotas class to reduce the likelihood that you will have to manually configure quotas for XML dictionary readers.

  • Validation of WCF configuration files by Visual Studio as part of the build process, so you can detect configuration errors before you run your application.

  • New asynchronous streaming support.

  • New HTTPS protocol mapping to make it easier to expose an endpoint over HTTPS with Internet Information Services (IIS).

  • Ability to generate metadata in a single WSDL document by appending ?singleWSDL to the service URL.

  • Support for configuring services in code.

  • Visual Studio XML Editor tooltips for every configuration element and its properties that is part of the service configuration file.

  • ChannelFactory caching support.

  • The WCF binary encoder adds support for compression.

  • UDP

    Support has been added for a UDP transport which allows developers to write services that use “fire and forget” messaging. A client sends a message to a service and expects no response from the service.

  • IDN Support

    Support has been added to allow for WCF services with Internationalized Domain Names. This type of messaging is useful when a WCF service sends a burst of simple messages to a large number of clients simultaneously, where the reliable delivery of each message is less important than sending the message to all clients at the same time.

For more information, see What’s New in Windows Communication Foundation on msdn.

Back to top


7. Windows Workflow Foundation (WF)

Several new features have been added to Windows Workflow Foundation (WF) in the .NET Framework 4.5 Developer Preview. These new features include:

  • Ability to create state machine workflows.

  • Enhanced Workflow Designer features such as the following:

    • Enhanced workflow search capabilities in Visual Studio, including Quick Find and Find in Files.

    • Ability to automatically create a Sequence activity when a second child activity is added to a container activity, and to include both activities in the Sequence activity.

    • Panning support, which enables the visible portion of a workflow to be changed without using the scroll bars.

    • A new Document Outline view that shows the components of a workflow in a tree-style outline view and lets you select a component in the Document Outline view.

    • Ability to add annotations to activities.

    • Ability to define and consume activity delegates by using the workflow designer.

    • Auto-connect and auto-insert for activities and transitions in state machine and flowchart workflows.

  • Storage of the view state information for a workflow in a single element in the XAML file, so you can easily locate and edit the view state information.

  • A NoPersistScope container activity to prevent child activities from persisting.

  • Support for C# expressions:

    • Workflow projects that use Visual Basic will use Visual Basic expressions, and C# workflow projects will use C# expressions.

    • C# workflow projects that were created in Visual Studio 2010 and that have Visual Basic expressions are compatible with C# workflow projects that use C# expressions.

  • Versioning enhancements:

    • The new WorkflowIdentity class, which provides a mapping between a persisted workflow instance and its workflow definition.

    • Side-by-side execution of multiple workflow versions in the same host, including WorkflowServiceHost.

    • In Dynamic Update, the ability to modify the definition of a persisted workflow instance.

  • Contract-first workflow service development, which provides support for automatically generating activities to match an existing service contract.

For more information, see What’s New in Windows Workflow Foundation.

James W. Hurst

Back to top

Posted in Uncategorized | Leave a comment

Silverlight 5 is available in beta now

The next version of Microsoft Silverlight will be version 5.  You can download a beta and related tools right now from here.  Microsoft has an announcement and description page here.

You’ll also want to download the Silverlight 5 Beta Tools for Visual Studio 2010 SP1.

Here’re some of the new goodies:

  • Extend features of the “Trusted Application” model to the browser. When enabled via a group policy registry key and application certificate, this means users won’t have to leave the browser to perform complex tasks.
    • Host HTML content within the Silverlight application
    • Read/write files to the user’s My Documents folder.
    • Launch other desktop programs.
    • Access devices and system capabilities by calling into application COM components.
    • Have full keyboard support in full screen.
    • Call existing unmanaged code directly from within Silverlight with PInvoke.
  • Text Improvements
    • Multicolumn text and linked text container allow text to flow around other elements.
    • Tracking/leading control
    • Pixel snapping improves text clarity
    • Text layout performance is better
    • OpenType support is improved
  • Databinding is enhanced!
    • You can now set breakpoints on a binding and step through binding failures!
    • Implicit DataTemplates
    • Binding in style setters
    • The DataContextChanged event is introduced.
  • Performance Improvements
    • Reduced network latency by using a background thread for networking
    • faster XAML parser
    • Support for 64-bit operating systems
    • graphics rendering improvements
    • Hardware decode and presentation of H.264
    • Improved power awareness
    • Remote-control support
Posted in Graphics, silverlight, Software Design | Tagged | Leave a comment

Evil Design

The Worst (and totally unnecessary) Flaw

What is the “feature”, or flaw, that you find most annoying about Windows 7?

For me, it’s when the dam thing simply crashes on you.

I sometimes use my laptop as a GPS system. Why? Because I like to have a nice big map, using up the entire 15.6 inch screen to show all the nearby roads and towns to help give me a sense of how to get there. I don’t like to use that synthesized voice that wants to tell me where to go. Sometimes it’s wrong. Sometimes I want to do a little more than just drive from A to B. I like to explore. To see what the region looks like, or at least what it’s maze of roads looks like. So I use Microsoft Streets and Trips, with a GPS sensor. I like maps.

So, here I am driving along, with my laptop on the seat next to me. And glancing over at it once in a while to see if I’m on track. Now, mind you — diverting your eyes away from the road is already dangerous enough. Ideally, the display should be right up there on the dashboard. But I digress.. Generally it works fine. A quick glance, and it helps me stay on track and not have to worry and fret about guessing which road I should be taking.

Then — suddenly this!

WTF?!!!

Now, mind you — if you’re sitting at your desk at home, quietly slurping a latte when this thing appears, no big deal. But while I’m driving? WTF!!!

BTW, there is no option to kill this. You can Postpone it, but not indefinitely. The biggest problem, is that my laptop is going to go offline for many minutes (I don’t have a SSD in this one yet) at what could be a dangerously crucial moment. This is dangerous! Microsoft does not know what we will be doing with your laptop at the moment it decides to do it’s update thingy. So this sort of thing is an absolute No-No!

And this should be a heads-up to any of you who design software, or systems, and provide it with any kind of message-box type of user interaction.

Rule Number 1: Do NOT jerk the system away from the user’s work to do your housekeeping, unless it is absolutely, definitely, essential. You do not want a user who is driving on a road at night, or flying a plane, or piloting a ship – to have to fiddle with the mouse-pad or pointer-nubby to click on the Postpone button. And then have to do it again in 10 minutes!

Microsoft Streets and Trips is Microsoft’s own product. Why can’t it detect that I have the software running. And my position is changing. Nothing should interrupt my usage of the product at this time. I am not even online: why do I give a shit about updating the software at this particular instant? I just want my tool to work for me, without distracting me from what I need to be doing.

What you (the designer of said software) should do, when you conclude it’s necessary to interrupt, is provide an opt-in message-box, that times out after so many seconds. And if it times out without the user doing anything, then it just lets the computer be, to keep doing it’s thing without interruption, until sometime later when the computer is idle and it is an appropriate time to prompt the user again.

That is a fundamental rule of design: Do not interrupt the user with your house-keeping.

Get Your Basic Operation Straight

It is my conviction, and this seems to be totally common-sense to me – that a software product should mature over time and with each succeeding version iteration. That is what I was told about, for example, IBM mainframe software: over time, it got increasingly solid. With each new version, more bugs were fixed, performance got better – enough that, if new functionality was introduced – it nonetheless was a more solid product that the version before. Shit worked.

So what is up with the Microsoft Windows design team?

We are now (as of 2012/2/4) on version 7. Windows has been out.. how long? .. since before the word “latte” was universally known here in the US. There are indeed some features that I like about it. But this thing has bugs in it’s basic operation for which there is no excuse!

For example, in Windows Explorer, nearly every time I select a folder, after a few seconds it seems to leap back to some other folder and select that. I often have to scroll down a second time and re-select the folder that I want to view, again. Why? This annoys the shit out of me.

It’s not only Microsoft, with their glaring flaws in otherwise good products like Windows, Word, Windows Media Player, and Windows Live Writer – Apple’s iTunes is so bad I still haven’t figured out how to do a totally basic operation like move an .mp3 audio file onto my iTouch so I can listen to educational audios while I’m driving. Nothing on it’s user-interface tells me clearly how to do it. Inexcusable! Especially after investing all that time to make a pretty UI. Give your product to an utter newbie (not a 13-year-old girl – they seem to already know everything!) and make careful note of what operations cause them to have to search for how to accomplish them. Then go back to the drawing-board and make those dead-simple obvious.

 

James W. Hurst

Posted in Software Design | Tagged | Leave a comment

A Virtual Keyboard for your WPF apps

Keywords: WPF, Silverlight, keyboard, Unicode, XAML

GermanLayout

Sometimes having a software-based ‘virtual keyboard’ for your desktop applications can be a help.  You can provide a way for your users to enter characters that they don’t have on their physical keyboard. You can also circumvent a stealthy keylogger by entering passwords this way. And for writing letters or posts to readers in other languages, it can be a huge timesaver.

Thus, the VirtualKeyboard project. You can get the complete Visual Studio solution from the CodePlex project here. I built it using Visual Studio 2013, however projects for earlier versions of Visual Studio (and targeting earlier versions of the .NET Framework) are included.

RussianLayout

This was a fun project done to do in Windows Presentation Foundation (WPF) – and I thought it’d provide a useful article to y’all because of the range of design techniques it uses. WPF yielded a few side-bennies like the fact that you can resize this Window and all the keys resize themselves appropriately. That was a freebee, by virtue of the Grid control.  Of course, I consider WPF to be a delight to design with; it’s the premier GUI-design platform out there and I have great respect for it’s creators. That said, this project does represent a significant amount of work. Let me rephrase that: a lot amount of work, to get it right. And then to boil it down to it’s essentials to the fairly compact application you see before you. I’m sharing this with you, to save you time on your projects and to illustrate techniques. Please give your feedback and contribute your own improvements so we can evolve this to make it even more useful. If you send me your suggestions, I’ll edit them into the code upon the next revision and cite you as the contributor. Multiple minds are always superior to just one.

We’ll walk through it’s design, have a little fun, and provide a link so you can download the entire demo application and source-code so you can put it to immediate use.

The VirtualKeyboard in operation:

It’s a non-modal dialog window, actually a WPF Window, which, if you integrate it into your application – allows you to provide a way for your user to invoke it and click on the key-buttons to insert characters into your application text fields.

DemoAppWithHands2

I’ve provided it with several language modes as a starter, and a brilliant gentleman named Iyengar Sesharaman did a beautiful job contributing two additional language sets – Sanskrit and Tamil – plus enhanced the code! My immediate need was for a memorization flash-card program to learn various language terms as in Arabic or Russian, so that’s what I created first. It also has French, German, and Spanish, which only actually add a few locale-specific characters. Perhaps you can tackle implementing a Mandarin keyboard and send to me to be included – I’d love to see!

You select the keyboard-layout via the ComboBox at the lower-right corner. Changing the language causes the keyboard to automatically update itself.

I found most of the keyboard-layout information on wikipedia and the like. I have to warn you though: that’s a good way to get utterly distracted and wind up delving into the historical underpinnings of ligatures and linguistics and whatever else catches your roving eye. But anyway – I strongly advocate for simplification via standardization. Hence, I try to select the one layout that is most appropriate as a standard for a given language/culture, but not go so far as to bastardize the standard US keyboard form itself. I can see that for some languages, that is not going to be an easy balance to choose. That arrangement should be chosen (by my reasoning) to most resemble what a native speaker would most likely be used to, within the confines of the standard keyboard layout. We are not selecting a Culture/Language for the GUI, after all. That’s a different topic altogether.

Anyway..

ColorfulFrog_wAs a further aid in typing, along the bottom edge, are thirteen extra typographic symbols you can type. I’ve needed these a lot.

In the demo-app pictured above you can see that there are two text fields. One is a TextBox, the other a RichTextBox. The virtual keyboard (VK) works the same with either one. Whichever text field has the current focus, that’s the one who receives whatever is typed into the VK.

The keyboard has provisions for saving it’s state, in that the next time you invoke it it’ll preset to the last language you used, and it’ll also remember whether you had it up whence you last exited your application, so it can auto-launch itself next time.

As a further convenience, just for kicks n giggles – when you move your application around on the screen, this keyboard Window can move in sync with it.

The key ToolTips are a convenience to the user, to help identify what the key is. I was tempted to insert the entire history of each glyph in there. However, this application/tool is for helping the person of the current Culture, type characters that happen to come from a foreign alphabet (relative to that user). Thus the ToolTips are in English (by default) to identify what those glyphs are. For this application, those ToolTips can be important.

When you click on the CAPS LOCK key, all the letters shift to uppercase. It stays in this state until you click CAPS LOCK again.

When you click on the SHIFT LOCK key, you have access to the shifted-state key symbols that you see on the keycaps, in addition to capital letters. This is the same as a physical keyboard does. In this case, after a ten-second timeout it drops back down to the unshifted state.

The Control and Alt keys do nothing. I just left them there so it looks more like a standard (US English) keyboard. But you can put those to use for something like the dead-letter keys that certain keyboards use languages. Or just remove them.

The Platform

This I originally created using Visual Studio 2010, on Windows 7 x64, and targeted the .NET Framework 4. Now I do my development using Visual Studio 2013 on Windows 8.1.  I did not test it on earlier versions.  I’m a believer in letting the vendors evolve our tools and taking advantage of the latest versions. If you’re one of those still stuck on version 1.0, because you’re so ultra-conservative – all I can say is: go away!  I have a separate library that this and all my other projects use, but I pared it down for this project download to just the bare minimum that it uses and included it with your source download. That ‘common’ base-level library is BaseLib, which I use for both desktop apps and web apps. Another library, BaseLibWpf, contains the WPF-specific common facilities; I separated that out because I didn’t want to be deploying desktop-specific assemblies with my online applications.

I set the configuration to target “Any CPU”. And that took a bit of tinkering. I’m unsure why. It kept flipping itself back to x64. When VS 2010 on Windows x64 suddenly seems to not be recognizing certain of your projects, check the build configuration. If one is x86 and the other x64, they will definitely cap your swagger! It can take several attempts before the setting sticks. (update: I haven’t seen that behavior as yet, with VS 2013).

I’m sure you want to know how to put it to use within your own program. Then we’ll chat about a few interesting aspects of it’s design, and then finally walk through the code itself.

Using it for your own application

The easiest way to tell how to use the VK in your own design, is to show you a simple demo-app that does just that. Let’s mosey through it in three steps.

Using it within your own Application is easy. The demo app that comes with your download is a pared-down WPF application that has a simple TextBox to receive the characters, and a Button for launching the virtual keyboard. And.. I added a 2nd text control, a RichTextBox, to illustrate using the VK for multiple input fields.

Here’s the XAML for the demo-app:

<Window x:Class=“JhVirtualKeyboardDemoApp.MainWindow”
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml&#8221;
Title=“JhVirtualKeyboard Demo Application, by James W. Hurst” Height=“247” Width=“359” Background=”{StaticResource dialogBackgroundBrush}>
<DockPanel LastChildFill=“True”>
<StackPanel Orientation=“Horizontal” HorizontalAlignment=“Right” DockPanel.Dock=“Bottom” Margin=“0,8,10,8”>
<Button Name=“btnVK” Margin=“5,0” Width=“96” Click=“btnVK_Click”>Virtual Keyboard</Button>
<Button Name=“btnClose” Margin=“5,0” Width=“80” IsCancel=“True” Click=“btnClose_Click”>Exit</Button>
</StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=“Auto”/>
<RowDefinition Height=“*”/>
<RowDefinition Height=“Auto”/>
<RowDefinition Height=“*”/>
<RowDefinition Height=“Auto”/>
<RowDefinition Height=“Auto”/>
</Grid.RowDefinitions>
<Label Name=“lblTextBox” Margin=“25,0,0,0” Padding=“5,5,5,0”>TextBox:</Label>
<TextBox Name=“txtBox” Margin=“20,0,20,10” FontSize=“16” Grid.Row=“1” GotFocus=“txtBox_GotFocus” ToolTip=”{Binding Path=ToolTipForTextBox} IsEnabled=”{Binding Path=IsEnabled} ToolTipService.ShowOnDisabled=“True” />
<Label Name=“lblRichTextBox” Margin=“25,0,0,0” Padding=“5,5,5,0” Grid.Row=“2”>RichTextBox:</Label>
<RichTextBox Name=“txtrichBox” Margin=“20,0,20,5” Grid.Row=“3” GotFocus=“txtrichBox_GotFocus” ToolTip=”{Binding Path=ToolTipForRichTextBox} IsEnabled=”{Binding Path=IsEnabled} ToolTipService.ShowOnDisabled=“True” />
<CheckBox Name=“ckbxEnable” Margin=“20,10,0,0” Grid.Row=“4” Content=“Enable the text controls” IsChecked=”{Binding Path=IsEnabled} />
</Grid>
</DockPanel>
</Window>

Mainly there’s a TextBox and a RichTextBox. The DockPanel on line 1 is there simply as a convenience for sticking the buttons along the bottom. I’ve been in the habit of throwing the DockPanel in there everytime I create a new Window. Note that when you set a Label over another field, if you want it to get quite close you have to set it’s bottom-padding to zero as well as it’s bottom-margin. I leave the other sides at the default padding value of 5.  In some cases I’ve had to use a negative bottom-margin to get it to nudge as near as I wanted. Tried that same method with a girl at the theatre, but that didn’t have positive results.

The two buttons have click-handlers which serve to launch the virtual keyboard, and to close the application.

I use a certain coding formatting standard in all our projects, which I’ve detailed here.

Let’s check out the code-behind for this MainWindow. Here’s the constructor..

  1. using System;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4. using Hurst.VirtualKeyboard;
  5. namespace Hurst.VirtualKeyboardDemoApp
  6. {
  7.     ///<summary>
  8.     /// The code-behind logic for our MainWindow.
  9.     ///</summary>
  10.     public partial class MainWindow : Window, IVirtualKeyboardInjectable
  11.     {
  12.         // The constructor
  13.         public MainWindow()
  14.         {
  15.             InitializeComponent();
  16.             _viewModel = new ViewModel();
  17.             // Remember which text field has the current focus.
  18.             _txtLastToHaveFocus = txtBox;
  19.             // Set up our event handlers.
  20.             this.ContentRendered += OnContentRendered;
  21.             this.LocationChanged += OnLocationChanged;
  22.             this.Closing += new System.ComponentModel.CancelEventHandler(OnClosing);
  23.             // Set the DataContext to our view-model.
  24.             DataContext = _viewModel;
  25.         }

You add a using pragma for the VirtualKeyboard namespace, and implement the IVirtualKeyboardInjectable interface as shown above. That interface is your contract with the virtual keyboard (VK) so they can interoperate.

Notice what we’re doing on line 20: we have an instance variable, _txtLastToHaveFocus, that serves to point to whichever text field has focus. We use this to tell the VK where to put it’s characters.

Notice also that we have three event handlers defined here. Let’s check these out.

The ContentRendered event handler:

void OnContentRendered(object sender, EventArgs e)
{
// If the Virtual Keyboard was up (being shown) when this application was last closed,
// show it now.
if (Properties.Settings.Default.IsVKUp)
{
ShowTheVirtualKeyboard();
}
// Put the initial focus on our first text field.
txtBox.Focus();
}

We have 3 things going on here.

1. As you can see on the first line within the method, it remembers whether the VK was up when we last ran this application. To achieve this, you simply add a boolean flag to your settings; in this case we named it IsVKUp.

2.  Invoke the VK using method ShowTheVirtualKeyboard. This is placed here, within the ContentRendered handler, because at this point your Window is already rendered and the VK can know where to position itself.

3. On the final line of code we set focus to the TextBox. Thus, you’ll still see the nice blinking caret in your text field, just as you would without the VK.

Here’s the ShowTheVirtualKeyboard method:

  1. public void ShowTheVirtualKeyboard()
  2. {
  3.     // (Optional) Enable it to remember which language it was set to last time, so that it can preset itself to that this time also.
  4.     VirtualKeyboard.SaveStateToMySettings(Properties.Settings.Default);
  5.     // Show the keyboard.
  6.     VirtualKeyboard.ShowOrAttachTo(this, ref _virtualKeyboard);
  7.     // (Optional) Call this for each text field for which you want the virtual keyboard to also remap your physical keyboard.
  8.     _virtualKeyboard.HandleKeysForControl(txtBox);
  9.     _virtualKeyboard.HandleKeysForControl(txtrichBox);
  10. }

This is where we fire up the VK.  You’re doing 2 things here.

1. By calling SaveStateToMySettings, you tell it how to save it’s state to your application settings. This is optional.

2. You call ShowOrAttachTo to launch the VK. You pass it the this pointer, so it knows who it’s owner Window is. You give it a reference to your local _virtualKeyboard instance variable, so you have a reference to it.

You need to implement the IVirtualKeyboardInjectable interface. Here’s how the demo app does this:

public System.Windows.Controls.Control ControlToInjectInto
{
get { return _txtLastToHaveFocus; }
}

By implementing the ControlToInjectInto property, you tell the VK where to send the characters that your user types into it.

If you have just one text field, you would simply return that (the instance-variable for the field). Here, we have two text fields. So we instead track which one has focus using this instance-variable, and return that in this property getter.

Let’s check out something else fun..

///<summary>
/// Handle the LocationChanged event, which is raised whenever the application window is moved.
///</summary>
void OnLocationChanged(object sender, EventArgs e)
{
// Do this if, when your user moves the application window around the screen,
// you want the Virtual Keyboard to move along with it.
if (_virtualKeyboard != null)
{
_virtualKeyboard.MoveAlongWith();
}
}

If you handle the LocationChanged event of your Window thus, then the VK will move around along with your Window, like it’s stuck to it. You can still position the VK itself relative to the application by manipulating it directly. Normally, I include a checkbox in my app’s Options dialog to give the user the ability to turn this on or off.  MoveAlongWith is a Window extension method that we’ll get to in a bit.

Oh yeah.. the click-handler that launches it.  Nothing remarkable here..

///<summary>
/// Handle the event that happens when the user clicks on the Show Virtual Keyboard button.
///</summary>
private void btnVK_Click(object sender, RoutedEventArgs e)
{
ShowTheVirtualKeyboard();
}

And here is the Closing event handler:

///<summary>
/// Handle the Closing event.
///</summary>
void OnClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
bool isVirtualKeyboardUp = _virtualKeyboard != null && VirtualKeyboard.IsUp;
Properties.Settings.Default.IsVKUp = isVirtualKeyboardUp;
Properties.Settings.Default.Save();
}

All this does, is save the Up/NotUp state of your VK to your application’s settings.

Tracking which field has focus:

This demo-app has two text fields so that you can see how to use your VK to serve input into more than one control.

What you need to accomplish this, is pretty simple. We added that instance variable, _txtLastToHaveFocus. This variable has to always be pointing to whichever field is currently holding the focus within your Window. How do we do this?

Simple. We hook up handlers to the GotFocus events of all the text fields, as here..

private void txtBox_GotFocus(object sender, RoutedEventArgs e)
{
// Remember that the plain TextBox was the last to receive focus.
_txtLastToHaveFocus = txtBox;
}private void txtrichBox_GotFocus(object sender, RoutedEventArgs e)
{
// Remember that the RichTextBox was the last to receive focus.
_txtLastToHaveFocus = txtrichBox;
}

As a result, that variable is always pointing to the correct field.

Settings:

I mentioned you need to add something to your application’s settings:

Settings

Here you can see I put two settings. The bool setting, IsVKUp, can be whatever you want to name it. The one that specifies the keyboard layout, though, must be named “VKLayout” or else VK won’t see it.

That’s it as far as how to use this within your own app. Simple, I trust? If you’ve any questions please feel free.

Let’s talk about the design a bit.

The Design of the Virtual Keyboard

I’m quite fond of object-oriented design, especially where it saves time and yields a more elegant creation. Checkit..

Here, we have keyboard layouts. These can be pretty detailed bits of information. Fifty-plus keys that change according to the language/alphabet, tooltips, and double that for the shifted/unshifted states, and then you have to treat the capital letters versus small letters, differently than the distinction between shifted/unshifted symbols. And there’re potentially hundreds of possible keyboard layouts.

On the other hand, some of these have a lot in common. And, considering the central role of the common US-std English-language keyboard, I based the root class of the hierarchy of keyboard layouts upon the English US keyboard to supply the default properties.

Thus, we have a conceptual scheme that begs of an object-oriented class hierarchy. At the top, the root class is the US keyboard layout. Everything else either inherits their stuff from that, or overrides it. Below that, at the second level, are the main variations. Russian (perhaps that should’ve really been called Cyrillic), Spanish, etc. And below that, could be further variations of those.

The economy of data arises when you consider that, e.g. the Spanish keyboard changes only a few things, but wants to leave everything else in place just as with the English US keyboard. So if we can let the Spanish keyboard inherit all the English keyboard features, it only has to override just those keys (and their tooltips, etc.) that it wants to change. The ideal OOP application.

To forge this scheme into our WPF XAML-based application that has fifty data-bound buttons, check it ..

ClassDiagram

If you look at the KeyAssignmentSet class in Visual Studio (VS), you’ll see it has a big honkn glob of instance variables and properties. One for every key-button of the keyboard. I named them “VK_A”, “VK_OEM1”, etc. to match the Win32 definitions.

The class KeyAssignmentSet represents the US English keyboard layout.

The subclass SpanishKeyAssignmentSet, overrides only those properties it wants to change. In this, just seven does the trick. That’s a lot easier than providing for all 50-plus key definitions. Suweet (hugging myself..).

Now, to make this work with our XAML design, merits a bit of intricacy. WPF likes to have stable view-models, to thus be a view of. The VK itself has a main view-model class: KeyboardViewModel. All the key-buttons have view-model objects that are members of KeyboardViewModel. Thus, to apply the appropriate KeyAssignmentSet to that view-model, we have an array of the individual key view-models, and we iterate across those assigning the information from the KeyAssignmentSet to them.

For this check out the method AssignKeys, in VirtualKeyboard.xaml.cs

In response, the WPF view updates itself automatically to reflect the new layout.

In this code I use the term “CodePoint” to refer to a spot within the Unicode standard that’s represented by a specific number, and depending upon which font you happen to be using – maps to a resulting glyph. Unicode is a wonderful resource; a massive amount of work was invested to wrest order and manageability out of the World’s chaos of languages and alphabets.   Here, I use the term “shifted CodePoint” to refer to the character on the upper portion of the key button, such as the Asterisk that is often over top of the digit-8 key.

Here’s the layout with the key-names shown:

VKwKeynames100

A few observations from the XAML of the VK..

xmlns:baseLibWpf=“clr-namespace:Hurst.BaseLibWpf;assembly=Hurst.BaseLibWpf”
xmlns:vk=“clr-namespace:Hurst.VirtualKeyboard”
baseLibWpf:WindowSettings.SaveSize=“True”

I bring in the namespace for the external utility library and assign it to the XML namespace prefix “baseLibWpf”. Then I do the same for the VirtualKeyboard assembly and assign that to “vk”. Note how the syntax varies: one is an external assembly, and the other is a local assembly hence doesn’t require the “;assembly=” part. This is one of those things that if you don’t get it right, you’ll spin wheels trying to figure out why your XAML isn’t recognizing your junk in your trunk.

I set the WindowStyle property to ToolWindow, and the FontFamily to a bound property on our view-model that hopefully yields a font that renders our layout nicely. Arial Unicode MS is one common font that seems to have pretty decent coverage of the non-Latin codepoints. But it doesn’t hurt to have some fun seeking out lovely fonts for this.

Let’s look at one of the key-button definitions:

            <Button Name=“btnSectionMark”
Command=“vk:VirtualKeyboard.KeyPressedCommand”
CommandParameter=“§”
Grid.Column=“2”
Height=“24”
Margin=“6,0,2,1”
ToolTip=“Section sign, or signum sectionis”
Width=“25”>§</Button>

This one injects the section-mark (also called the “signum sectionis” if you want to sound uppity). All the key-buttons use this same KeyPressedCommand, with the command parameter carrying the character to inject. Most of the formatting is set in a Style, but this one overrides the Margin, Width and Height to fine-tune the appearance.

Right now, looking at this XAML in LiveWriter, the button Content shows up with the syntax for the hexadecimal 00A7 value, with the ampersand, pound, x prefix and the semicolon suffix. But at the same time, the published version I’m looking at online in FireFox, shows the actual signum sectionis instead. Hmm..

I use a style for the key-buttons so that I don’t have to type in a ton of markup..

<Style TargetType=”{x:Type Button}>
<Setter Property=“Width” Value=“Auto”/>
<Setter Property=“Height” Value=“Auto”/>
<Setter Property=“FontSize” Value=“18”/>
<Style.Triggers>
<Trigger Property=“IsPressed” Value=“False”>
<!– This is here because we’re setting it slightly differently when the button is being pressed. –>
<Setter Property=“Margin” Value=“0,0,2,1”/>
<Setter Property=“Effect”>
<Setter.Value>
<DropShadowEffect Direction=“315” Opacity=“0.7”/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property=“IsPressed” Value=“True”>
<Setter Property=“Foreground” Value=”{StaticResource brushBlue}/>
<!– Shift the button downward and to the right slightly, to give the affect of being pushed inward. –>
<Setter Property=“Margin” Value=“2,1,0,0”/>
<Setter Property=“Effect”>
<Setter.Value>
<DropShadowEffect Direction=“135” Opacity=“0.5” ShadowDepth=“2”/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

This Style targets all Buttons, thus it becomes the default for all Buttons within that container.

I had to tinker with and fine-tune the sizes, padding and margins to get it to look right.

In the first version I had set the FontFamily to “Bitstream Cyberbase, Roman”. I purchased that due to it’s codepoint-coverage. But I found that different fonts are merited for different languages, so I made that a bindable property within the view-model.

The most interesting thing (well, to me anyway) in this Style is making the key-buttons visually float off the surface a bit, and then seem to push downward (and to the right slightly) when you click on them, to yield that cute 3D affect. As you can see from reading the XAML, the trigger fires when the IsPressed property becomes true. It reacts by setting the margin property to shift it’s position down and to the right, and changes the DropShadowEffect to get that 3D affect.

Here’re how the main key-buttons are defined..

<Button Name=“btnVK_Oem3” Grid.Column=“0” ToolTip=”{Binding Path=VK_Oem3.ToolTip}>
<Button.Content>
<TextBlock Name=“txtblkVK_Oem3”>
<Run Text=”{Binding Path=VK_Oem3.Text, Mode=OneWay}/>
</TextBlock>
</Button.Content>
</Button>
<Button Name=“btnVK_1” Grid.Column=“1” ToolTip=”{Binding Path=VK_1.ToolTip}>
<Button.Content>
<TextBlock Name=“txtblkVK_1”>
<Run Text=”{Binding Path=VK_1.Text, Mode=OneWay}/>
</TextBlock>
</Button.Content>
</Button>
<Button Name=“btnVK_2” Grid.Column=“2” ToolTip=”{Binding Path=VK_2.ToolTip}>
<Button.Content>
<TextBlock Name=“txtblkVK_2”>
<Run Text=”{Binding Path=VK_2.TextShifted, Mode=OneWay}/>
<Run Text=”{Binding Path=VK_2.TextUnshiftedNL, Mode=OneWay}/>
<Run Text=”{Binding Path=VK_2.TextAltGr, Mode=OneWay} Foreground=”{Binding Path=ColorForAltGr}/>
</TextBlock>
</Button.Content>
</Button>

The DataContext of this Window is the KeyboardViewModel. As you can see, the Content of these Buttons is set to the Text property of the VK_1, VK_2, etc. members of KeyboardViewModel. Each of those keybuttons implement INotifyPropertyChanged to keep the GUI apprised of their values when they change. The base class ViewModel implements that for us.

The ToolTip property is also data-bound to the view-model. Each of those KeyViewModel objects (ie, VK_1, etc) also has a ToolTip property.

A slight complication for me was that that Text property, and the ToolTip, needed to yield different values depending upon whether the shift key was in effect.

Here is how that is implemented within the KeyViewModel class …

#region ToolTip
///<summary>
/// Get the ToolTip, whether it corresponds to the unshifted, shifted, or Alt codepoints.
///</summary>
public virtual string ToolTip
{
get
{
if ((s_domain.IsShiftLock
|| (_isLetter && s_domain.IsCapsLock)) && !String.IsNullOrEmpty(_shiftedToolTip))
{
return _shiftedToolTip;
}
else if (s_domain.IsInAltGrState && !String.IsNullOrEmpty(_altToolTip))
{
return _altToolTip;
}
else
{
return _toolTip;
}
}
}public string UnshiftedToolTip
{
get { return _toolTip; }
set
{
if (value != _toolTip)
{
_toolTip = value;
Notify(“ToolTip”);
}
}
}public string ShiftedToolTip
{
get { return _shiftedToolTip; }
set { _shiftedToolTip = value; }
}public string AltGrToolTip
{
get { return _altToolTip; }
set { _altToolTip = value; }
}
#endregion

Here, _domain is a static variable that refers to our KeyboardViewModel. This selects between the unshifted, and the shifted, ToolTip value.

The Text property acts similarly, except that it selects from the key’s Text property if that was explicitly set, otherwise it returns the unshifted or shifted codepoint that was assigned to that key.


Showing the VK

Stretching hard to get to where we want to be

This merited a bit of tinkering. Probably there’s a better way to do this, but it’s what I was able to get to work. If you know of a better way, please share.

The exception-handling is something that you’ll want to adapt to your specific application; what I use here is just one example of a system-wide method.

Here’s the code…


///<summary>
/// Either create and show, or else re-attach to (if it’s already up) the virtual keyboard.
/// To be called from the desired target-Window that wants to use it.
///</summary>
///<param name=“targetWindow”>The Window that wants to be the owner of the virtual-keyboard Window and the target of it’s output</param>
///<param name=“myPointerToIt”>The targetWindow’s own instance-variable that will point to the virtual keyboard object</param>
public static void ShowOrAttachTo(IVirtualKeyboardInjectable targetWindow, ref VirtualKeyboard myPointerToIt)
{
try
{
_desiredTargetWindow = targetWindow;
// Evidently, for modal Windows I can’t share user-focus with another Window unless I first close and then recreate it.
// A shame. Seems like a waste of time. But I don’t know of a work-around to it (yet).
if (IsUp)
{
Console.WriteLine(“VirtualKeyboard: re-attaching to a different Window.”);
VirtualKeyboard.The.Closed += new EventHandler(OnTheKeyboardClosed);
VirtualKeyboard.The.Close();
myPointerToIt = null;
}
else
{
myPointerToIt = ShowIt(targetWindow);
}
}
catch (Exception x)
{
Console.WriteLine(“in VirtualKeyboard.ShowOrAttachTo: “ + x.Message);
IInterlocution inter = Application.Current as IInterlocution;
if (inter != null)
{
inter.NotifyUserOfError(“Well, now this is embarrassing.”, “in VirtualKeyboard.ShowOrAttachTo.”, x);
}
}
}

Yeah, it’s not the trivial call to ShowDialog that we’d expect, is it?

The complication is: if it was already showing, but owned by some other window, and this window (the one you’re actually trying to get to use the VK now) was launched modally, it can’t just “take ownership” of the VK Window. The only thing I could get to work, was to shut the VK down and then re-launch it.

Thus, here we tell the VK to close itself, and hook into the Closed event so that another method gets called after the VK closes. That other method, in turn, re-launches the VK.

A bit of usability testing revealed that your users, in attempting to enter their stuff using the mouse, preferred a shift-key that would reset itself. So, clicking on either of the shift keys pushes the VK into the shifted state, and then clicking on any character pops it back into the un-shifted state. But if the user delays, it resets itself after ten seconds. Here’s what does that..

///<summary>
/// Flip the state of the SHIFT key-button.
///</summary>
private void PutIntoShiftState(bool bShiftLock)
{
ClearTimer();
// Set the shift-lock state.
_domain.IsShiftLock = bShiftLock;
UpdateTheKeyBindings();// If we’re turning Shiftlock on, give that a 10-second timeout before it resets by itself.
if (bShiftLock)
{
// If we’re going into shift-lock state,
// regard the AltGr state as mutually-exclusive and turn that off.
_domain.IsInAltGrState = false;
// Set the reset-timer.
_resetTimer = new DispatcherTimer(TimeSpan.FromSeconds(10),
DispatcherPriority.ApplicationIdle,
new EventHandler(OnResetTimerTick),
this.Dispatcher);
}
SetFocusOnTarget();
}

Note that every time your user clicks on anything within the VK, the VK’s Window gets focus. Which is not what we want! Thus we follow that with a call to SetFocusOnTarget, which tosses focus back to your text field.

Doing the actual key character injection

Here is the method that actually inserts the character into your target text-field..

#region Inject
///<summary>
/// Type the given string into whatever the target TextBox (or similar control) is.
///</summary>
///<param name=“sWhat”></param>
public void Inject(string sWhat)
{
if (TargetWindow != null)
{
((Window)TargetWindow).Focus();
TextBox txtTarget = TargetWindow.ControlToInjectInto as TextBox;
if (txtTarget != null)
{
if (txtTarget.IsEnabled && !txtTarget.IsReadOnly)
{
if (_domain.IsFlowDirectionLeftToRight
|| (!_domain.IsFlowDirectionLeftToRight && !_domain.IsForcingLeftToRight))
{
txtTarget.InsertText(sWhat);
}
else  // the FlowDirection is backwards, but the user wants to force it to insert LeftToRight.
{
txtTarget.InsertTextLeftToRight(sWhat);
}
MakeKeyPressSound();
}
else
{
if (!txtTarget.IsEnabled)
{
SetStatusTextTo(“Cannot type into disabled field”);
}
else
{
SetStatusTextTo(“Cannot type into readonly field”);
}
}
}
else
{
RichTextBox richTextBox = TargetWindow.ControlToInjectInto as RichTextBox;
if (richTextBox != null)
{
if (richTextBox.IsEnabled && !richTextBox.IsReadOnly)
{
richTextBox.InsertText(sWhat);
MakeKeyPressSound();
}
else
{
if (!txtTarget.IsEnabled)
{
SetStatusTextTo(“Cannot type into disabled field”);
}
else
{
SetStatusTextTo(“Cannot type into readonly field”);
}
}
}
else // let’s hope it’s an IInjectableControl
{
IInjectableControl targetControl = TargetWindow.ControlToInjectInto
as IInjectableControl;
if (targetControl != null)
{
targetControl.InsertText(sWhat);
MakeKeyPressSound();
}
}
//else   // if you have other text-entry controls such as a rich-text box, include them here.
//{
//    FsWpfControls.FsRichTextBox.FsRichTextBox txtrTarget
//     = TargetWindow.ControlToInjectInto as FsWpfControls.FsRichTextBox.FsRichTextBox;
//    if (txtrTarget != null)
//    {
//        txtrTarget.InsertThis(sWhat);
//    }
}
}
}///<summary>
/// Inject the character represented by the given “key” switch view-model, into whatever the target TextBox is.
///</summary>
///<param name=“vm”>The KeyViewModel that carries the information of what to inject</param>
public void Inject(KeyViewModel vm)
{
// The Tag would’ve been another way to associate the view-model with the button.
if (vm != null)
{
if (vm == _domain.EnterKey)
{
Inject(Environment.NewLine);
}
else
{
Inject(vm.CodePoint.ToString());
}
}
// If we were in Shift-mode, reset that now.
_domain.IsShiftLock = false;
ClearTimer();
}
#endregion

This part can merit a bit of thought. Out-of-the-box, I have provided for two possible controls: a TextBox, and a RichTextBox.

I make a call to your method ControlToInjectInto, to get a reference to what to put the character into. I try to find what it is by casting it to first one type and then another.

For either of these, I defined an extension method InsertText, to do the actual text insertion. Which was surprisingly non-trivial.

In an effort to accommodate you custom-text-box creators, I also defined an interface IInjectableControl. If you have a text field that is neither a TextBox nor a RichTextBox, if you can make your control implement this interface, it’ll still work. Otherwise, you’re going to have to modify this code to make it work for you. Well, that’s the great thing about getting a project complete with source-code, isn’t it? You’ll need to code for your control here, and also in the method DoBackSpace – which btw uses the built-in editing command EditingCommands.Backspace to actually do the BACKSPACE. It was actually simpler to just manipulate the text directly. But I wanted to play with the commanding approach. So I add a command-binding to this control at this point, use that to execute the Backspace operation, and leave that command-binding in place until the keyboard closes at which time we clear it.

The Extension Methods

Here’s the InsertText extension method for TextBox, which you’ll find in BaseLibWpf.WPFExtensions.cs

///<summary>
/// Insert the given text into this TextBox at the current CaretIndex, and replacing any already-selected text.
///</summary>
///<param name=“textbox”>The TextBox to insert the new text into</param>
///<param name=“sTextToInsert”>The text to insert into this TextBox</param>
public static void InsertText(this System.Windows.Controls.TextBox textbox, string sTextToInsert)
{
int iCaretIndex = textbox.CaretIndex;
int iOriginalSelectionLength = textbox.SelectionLength;
textbox.SelectedText = sTextToInsert;
if (iOriginalSelectionLength > 0)
{
textbox.SelectionLength = 0;
}
textbox.CaretIndex = iCaretIndex + 1;
}

Yeah, looks a bit verbose.

Here’s the InsertText extension method for RichTextBox:

///<summary>
/// Insert the given text into this RichTextBox at the current CaretPosition, replacing any already-selected text.
///</summary>
///<param name=“richTextBox”>The RichTextBox to insert the new text into</param>
///<param name=“sTextToInsert”>The text to insert into this RichTextBox</param>
public static void InsertText(this System.Windows.Controls.RichTextBox richTextBox, string sTextToInsert)
{
if (!String.IsNullOrEmpty(sTextToInsert))
{
richTextBox.BeginChange();
if (richTextBox.Selection.Text != string.Empty)
{
richTextBox.Selection.Text = string.Empty;
}
TextPointer tp = richTextBox.CaretPosition.GetPositionAtOffset(0, LogicalDirection.Forward);
richTextBox.CaretPosition.InsertTextInRun(sTextToInsert);
richTextBox.CaretPosition = tp;
richTextBox.EndChange();
Keyboard.Focus(richTextBox);
}
}

This took a bit of tinkering, just to get to insert a simple character. It’s not as simple as simply appending to the text: if the caret is not at the end, you have to insert at the caret and slide everything to the right (speaking in terms of array-indices).

Conclusion

So, there you have it – a working screen-based virtual keyboard created using C# and WPF. I hope this is useful for you, and that you’ll give me your thoughts and suggestions.   I find WPF fun to work with: it feels so natural now that I dislike using anything else for a desktop GUI application. But there’s always new bits to learn. Next up – a Mac and Linux implementation.

This project was introduced as an article on The Code Project.

This project is also published on CodePlex, which is also a convenient place for you to participate in discussion on this project.

James Witt Hurst

Posted in C#, CodeProject, silverlight, Software Design, The .NET Framework, WPF | Tagged , | 37 Comments

Visual Studio/Live Writer tip: format as code

If you need to post a blog article containing code, and you happen to be using Visual Studio 2010 (VS), there’s a nice tool that provides an easy way to preserve it’s formatting and syntax coloration as it appears within VS.

It’s an extension for Windows Live Writer, created by Tim Mathius, which you can find here

Download this extension using the button on the webpage. Launch the .msi file to install it. Now from within VS you just select your code, CTRL+C to copy it to the clipboard, and then go over to your Live Writer blog and in your main menu-bar, select Insert > Paste As VS Code… and ahhhh… check it!  You also get a nice panel of options to set, and you can save your custimizations as a default.

  1. namespace RLib
  2. {
  3.     /// <summary>
  4.     /// Providing this interface helps contribute a sort of 'aspect-oriented programming' structure
  5.     /// by interjecting an Interlocution and other subsystems across the board.
  6.     /// </summary>
  7.     public interface IApp
  8.     {
  9.         /// <summary>
  10.         /// Provide access to the Interlocution class that provides us with the various notification and logging services.
  11.         /// </summary>
  12.         IInterlocution Interlocution { get; }

 

Very nice Tim!!!

by james w. hurst


							
Posted in CodeProject, Visual Studio | Tagged | 2 Comments

WPF Tip #1: avoid App.Current.Shutdown

In your WPF application’s Exit command handler, be wary of calling App.Current.Shutdown unless you want to bypass the normal ‘Close’ process. It can result in your override of OnClosing to NOT be called, and your closing-event handlers don’t get called either.

If you override the Onclosing method, don’t forget to call the base class OnClosing!

Oh – if your WindowSettings functionality is not working, check for this mistake.

Of course I’ve never done that myself. Oh no. Neeeever.

james hurst

Posted in WPF | Tagged | Leave a comment

Databinding in WPF/SilverLight

One of the more interesting features of the WPF/SilverLight framework, is databinding. And also one of the more confusing. I’m going to list a few tips here, to serve as a cheat-sheet..

By “source property” I mean that bit of data from which we are taking our value, and the “target property” is what we’re setting. The target property has to be a Dependency Property (DP), but the source can be just about anything.

If you’re going to bind to something that shouldn’t be evaluated until runtime, provide a reasonable default value for your designer to show, and use the following to distinquish which mode you’re in:

Code Snippet
  1. using System.ComponentModel;  // for DesignerProperties
  2. namespace WumPut.DialogWindows
  3. {
  4.     public partial class SampleWindow : Window
  5.     {
  6.         public SampleWindow()
  7.         {
  8.             if (!DesignerProperties.GetIsInDesignMode(this))
  9.             {
  10.                 // not in Design-Mode.
  11.                 this.Title = “Some value thats determined at runtime.”;
  12.             }
  13.             InitializeComponent();
  14.         }

On line 9 of this code snippet, you’re using DesignerProperties.GetIsInDesignMode to determine whether you’re in the VS Designer, or are operating at runtime. To get access to this, include using System.ComponentModel; as shown on line 1.

Here’re some common scenarios..

1. To bind a scalar property of a WPF element to a DP of another WPF element:
(for example)  FontSize=”{Binding ElementName=slider1, Path=Value}“. The curly braces indicate a markup extension.

2. If you want to bind to an attached property of that element, wrap that property in parenthesis. For example, Path=(Grid.Row)

3. To bind to something on a parent element (ie, further up the visual tree):
<TextBlock Text={Binding Path=Title, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}} }

For RelativeSource, ‘FindAncestor’ is just one of several values. It takes a RelativeSourceMode which may be Self, FindAncestor, PreviousData, or TemplatedParent.

4.To set it as a bidirectional binding..
<TextBlock FontSize={binding ElementName=slider1, Path=Value, Mode=TwoWay}

5. For TextBoxes the default behavior is to update the binding upon LostFocus. If you want the trigger to fire as soon as the source content changes, you need to set the UpdateSourceTrigger to PropertyChanged.

6. You can assign a value for the target to take for when the source is null, by using the TargetNullValue property.

For example: <TextBox Text={Binding ThatSourceProperty, TargetNullValue=0″} />

7.. and you can ue the FallbackValue property for defining what the target value will be in the event of an error:

<TextBox Text={Binding ThatSourceProperty, TargetNullValue=0, FallbackValue=1″} />

8. To create that binding in code:
Binding binding = new Binding();
binding.Source = slider1;
binding.Path = new PropertyPath(“Value”);
binding.Mode = BindingMode.TwoWay;
lblSampleText.SetBinding( TextBlock.TextProperty, binding);

You also have available to you in code..
BindingOperations.ClearBinding(..)
BindingOperations.ClearAllBindings()

To get the BindingExpression of a WPF element:
BindingExpressing binding = txtFontSize.GetBindingExpression(TextBox.TextProperty);

9.To bind to objects that aren’t WPF elements:
The information must be in public properties, and instead of ElementName you use one of..
Source
RelativeSource (relative to the current WPF element, i.e.)
DataContext

To bind to a class using a static property (to access an instance of it):
<TextBlock Text=”{Binding
                                    Path=UserName,
                                    Source={x:Static local:Properties.Settings.Default}}” />

Here, Properties is actually the namespace in which class Settings is defined, and Default is a static property that returns an instance of the Settings class. This example is from p59 of Programming WPF.

Note: To bind to your own non-UI class and have your target value update itself as the source property changes, you can implement the INotifyPropertyChanged or the INotifyCollectionChanged interfaces. Before .NET 4 these interfaces were part of the WindowsBase WPF assembly so it was not possible to make your bindings work without referencing that library. As of .NET 4.0 however, the INotify.. interfaces have been type forwarded to System.dll.

10. To bind to something from the .NET class library:
(for example) <TextBlock Text=”{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=Source}”>

11.To bind to an object that you’ve created as a resource:
<Window.Resources>
    <FontFamily x:Key=”CustomFont”>Calibri</FontFamily>
</Window.Resources>

<TextBlock Text=”{Binding Source={StaticResource CustomFont}, Path=Source}”>

12.To bind to a property of the Window itself:
<TextBlock Text=”{Binding Path=Title, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}} }”>

13.To bind to a collection, as in the case of an ItemsControl — which includes the ListBox, ComboBox, and ListView:
<ComboBox ItemsSource=”{Binding Path=Constants.AllowableZoomValues, Mode=OneWay}”
-but don’t forget to set the DataContext in either XAML or your code-behind.

14. The ComboBox.
When I speak of a ‘scalar’ value, I mean a single bit of data, such as an integer or a string. But when we’re talking about a ComboBox or ListBox — these take a collection to be bound to their itemscontrol.

The ComboBox has the ItemsControl property for specifying this. Thus you have a collection of objects to display in it’s drop-down list. But what do you actually show for each element of that list?

ComboBox has the DisplayMemberPath property to specify this. If you set this to a property name that exists on the elements of that collection, the value of that property is what will be displayed.

Let’s take an example: Say we have this simple class..

public class HairyThing
{
public int Id { get; set; }
public string Name { get; set; }
}

and a collection of these defined somewhere within our XAML as a static resource.
We can bind to it as in this XAML..

<ComboBox Name=”cbHairyThings”
ItemsSource=”{Binding Source={StaticResource HairyThings}}” />

This would display the elements by calling their ToString methods. Usually not what you want.

If you change it thus..

<ComboBox Name=”cbHairyThings”
ItemsSource=”{Binding Source={StaticResource HairyThings}}”
DisplayMemberPath=”Name” />

Now it properly displays the Name of the hairy things within the ComboBox and for each item in it’s drop-down list.

If your user selects some item within that ComboBox, you can access that selected value via it’s SelectedItem property..

cbHairyThings.SelectedItem = theHairyThing; // to set the current selection within the ComboBox

var selectedHairyThing = (HairyThing)cbHairyThing.SelectedItem;

ComboBox also provides two other useful properties that relate to our data-binding: SelectedValue and SelectedValuePath.
SelectedValue acts like a more precisely specified SelectedItem. Instead of assigning an entire HairyThing object to it, as you do with SelectedItem, you assign a key property like Id or Name – depending upon the setting of SelectedValuePath.
SelectedValuePath specifies which property to use. If you set SelectedValuePath to Name, then SelectedValue will access the Name property of whatever HairyThing object the SelectedItem is currently bound to.
For example, if you set to Id, as here..

<ComboBox Name=”cbHairyThings”
ItemsSource=”{Binding Source={StaticResource HairyThings}}”
DisplayMemberPath=”Name”
SelectedValuePath=”Id” />

Then when a call to cbHairyThings.SelectedValue gives you back the Id of the currently selected HairyThing..

int id = cbHairyThings.SelectedValue; // Get the Id of the current selection.

cbHairyThings.SelectedValue = 3; // Set the current selection of the ComboBox to the object that has an Id of 3.

I’ll be updating this note as I need to describe the operation of the ComboBox, and to cover more scenarios. Feel free to hit me up with your questions. Best of wishes,  James W. Hurst

Posted in WPF | Tagged | 1 Comment

A Note re Scanning and Capturing Images

 

EyeParrot_w

Scanning:

When you’re scanning something, what file-format is best to use? Your scanning software will usually offer the choices of JPG, TIF, GIF, and PNG (or, PNG-8 and PNG-24). Or it may hide these behind the more generic “Document” or “Photograph” settings. The rule is simple, but most scanning software doesn’t really help to guide the user.

I generally use PNG-24.

About these formats..

The JPEG format yields files that end with the “.JPG” extension. This format compresses images to a smaller size (by “size”, I mean how much space it takes up on your disk). This is useful, but it comes at a price: it’s lossy. It dumps some information from the image, in order to squish it down. It works okay for photographs, depending upon your intent, because it’s designed to dump those parts that your eye won’t miss (much).  Are you going to do things to this image in Photoshop or other graphic progam? Then you do not want to use this format. It’s like recording audio onto magnetic tape in analogue format: with every generation of recording, you lose more information and it becomes increasingly degraded. In this case, it can be quite visually obvious very quickly.

The GIF file-format is not lossy in the same way. But it only captures the colors to a depth of 8 bits. That’s 8 bits total, not 8 bits per color. This is appropriate only if you’ve less than 256 colors in your image, and those are easily represented. Here, a sheet of white paper, with black lettering, is a good candidate. The GIF format will happily compresses all that white space. And it includes an ability to encode one of those 256 ‘colors’ as a transparency bit, meaning underlying colors will show through.

The PNG format is a successor to the older GIF format and is not a proprietary format as GIF is. It comes in two flavors: PNG-8 and PNG-24. PNG-8 is analogous to the GIF format in that it uses 8 bits to represent each pixel of the image, meaning it too can only encode 256 colors at a time.  But PNG-24 offers a full 24-bit range of colors for each pixel. It also offers the ability to display transparency, but now it’s a full 8-bit “alpha”, meaning it can show varying levels of transparency.

So which to choose?

If you choose PNG-24, your files will be larger. But they’ll contain all the image color information. They’re not “squished down”. You can open them in your favorite image-editing program and produce a highly-compressed JPEG from it anytime you want, with no ill effects on your original .PNG file.

I’d only save your original images in the JPEG format if you don’t really care about keeping or manipulating them in your image-editing program. If you’re scanning a photograph, and it produces JPEG files that are already small enough to send by email or post online, and that’s all you’re ever going to want of them, then have at it. Save it as JPEG. But if you use JPEG for your non-photograph documents, you’ll see ‘artifacts’ of the compression process around the lines and letters that degrade it’s appearance.

So in general, use PNG-24.

What about Dot Pitch?

For the same reason as above, I usually scan images at a pixel-resolution that is a bit higher than I’ll ultimately need, in order to have a more perfect ‘source’-image that I can then down-sample when needed.

For documents, I sometimes scan at 200dpi (dots per inch) if it’s a clear paper with easily-legible fonts, but generally I go to 300dpi or even higher if it merits the higher resolution.

When scanning pictures from a printed media such as a magazine, actually 75dpi or 150dpi would usually do except that you have the possibility of the moire effect messing up your image file. That, is an interaction between the scanner’s resolution, and the dot-pitch on the printed page. That can really make it ugly!

Thus for magazine photos, I avoid that by using an overly-fine resolution like 600dpi to scan the original, then I down-sample in Photoshop to reduce the resulting huge file. This is “over-sampling”. It does cure the problem. The caveat being that scanning is slower at this resolution, and the file sizes can be rather large. Even newspaper articles have this moire-effect problem and you may need to over-sample, even though the newspaper is only printed with a dot-pitch of perhaps 75 dpi. Some scanning software has a ‘compensate for moire effect’ option, which you may want to try out. Otherwise, it is a waste of disk space to scan at more than twice the resolution that the image was originally printed at.

Yes, it is an extra step – to fire up your image-editing program to down-sample your image file, or convert it to JPEG, etc. But usually you would have to do this anyway, to do a reasonably-precise job of cropping it, making it perfectly horizontal (ie, not tilted), and other processing tasks.

For other scanning tasks such as simple posters, or large photographs that don’t have a lot of fine detail or aren’t extremely sensitive in nature, it is a waste of disk space and time to scan at an excessively fine resolution. Tinker a bit, and find the resolution that gives you the results you want, and no higher.  For a large crude photograph, perhaps just 75 dpi and save it as JPEG. For a poster that has only a couple of colors, the PNG-8 format will do fine and often can yield a smaller file.

Higher Color-Depths

In this discussion of color depths where I state that PNG-24 will capture your full range of color information, I’ve bypassed the issue of color depths higher than 24 bits-per-pixel. 24 bits provides 8 bits per color, and is generally fine for a photo-realistic result. But some digital cameras are now yielding more than this. The newer Nikon and Canon DSLRs, for example, produce 14 bits per pixel in their sensors. As soon as you save it as JPG, you lose that extra information. The only option to preserve that image information is to save it as a ‘RAW’ –format file, which is the camera manufacturer’s own file format that preserves all the original color information. You can bring that into Photoshop CS4 and still preserve that higher color-depth, because Photoshop is capable of using 16 bits per color channel.

Similarly, some scanners now can save an image in a high color-depth format. In general, your workflow should depend upon your need. For common business-usage, you’ll never have need of more than 24 bits per pixel. If you’re scanning your great-uncles’ masterful oil painting that’s been hanging in a museum, you do want to preserve the full range of color information. For other images, that extra depth becomes useful only if you’re planning to manipulate the image extensively in Photoshop such that the higher color-depth stands up against loss of color information that comes from numeric rounding-errors that result from every processing step. But that’s a topic for a real Photoshop article.

Posted in beginner, Graphics, Microsoft Windows tips and techniques, Personal Effectiveness | Tagged , , , | 1 Comment

SilverLight 4 beta is now available!

WomanSittingOnBeach(Note: This is a November 2009 post and this information is obsolete. You can find information on the new SilverLight 5 here).  Silverlight 4 is available in beta form, as of 2009 November 18th.  Here is where you can download it from Microsoft’s SilverLight site.

You’ll want to download and install Visual Studio 2010 beta 2 (VS), or Visual Web Developer Express 2010 beta 2 if VS is too heavy for you, to develop for SilverLight 4. Yes, you can install it side-by-side with VS 2008 SP1. Other important tools to add to your toolbox include Microsoft’s Expression Blend for .NET 4 Preview, and the SilverLight 4 beta Tools for Visual Studio (which installs the SilverLight 4 SDK).

Posted in Uncategorized | Tagged | Leave a comment

The C# Code-Formatting Standard

Image of an otter pocking his head up through a lot of green muck

Digging into an existing software project of significant size can be confusing and, without a clear structure and organization of the code and the documentation, can result in a lot of wasted time. Structure guides and clarifies, and self-documents. Well, ideally. You can have an excess of structure – which can comprise an intellectual road-block. Later on that.

Here are some standards for structuring and formatting our code. This has evolved over many years of involvement in large projects involving C, C++, Java, and C# – especially in the aerospace and defense industries. For the examples I’m going to assume the programming-language is C#, and the GUI toolkit is WPF, SilverLight, or ASP.NET. These standards also apply (with the obvious adaptation) to Winforms, C++ or Java. I’m also going to assume the IDE is Microsoft’s Visual Studio 2012 (VS).

Region Organization

Public Interface

Internal Implementation

Automated Tests

There is one all-important standard for your test code: At the top of your code file, put a TEST REQUIREMENTS comment that clearly states everything that test needs in order to run. Put all of the requirements that must be met apart from that of the code itself, the platform that it must be on, the preparation and cleanup that need to happen, everything. Do this for every file that contains test-code, and make absolutely certain that your team-members read this and concur. If you add a unit-test to this file, update the TEST REQUIREMENTS to make sure is is current and correct.  This will save you at scrunch-time!

By “automated test” I am referring here to unit-tests, subsystem-tests, or system tests — that can be invoked to run without human interaction. This requirement really is for what we commonly refer to as subsystem-tests — those that access other things such as web services, the file-system, or a database.  The naming convention varies, but the vital consideration is that, if you are using Test-Driven-Development (TDD) in your department, then these have to run and they need to pass. Machines go down, infrastructure changes, databases come and go — and you do not want to find yourself holding up everyone else on your team, late on Friday when everyone wants to go home, because the tests are suddenly failing.  That TEST REQUIREMENTS section is vital.

Coding Standards

Class Instance Variables (ivars):

For private variables, use the single underscore (“_”) prefix. E.g..

_productType;
_name;

Caveat: for protected or public variables, if you want to mark your assembly as CLR-complaint you will need to NOT use the leading underscore, so in that case you could use the leading “m_” instead. If you use this just for protected variables, you now have two distinct naming styles, which may or may not be advantageous.

Previously in C++, in Microsoft, etc. some were using “m_” as the prefix, the “m” representing a “member” variable. Which would seem to make some sense. The advantage of using just the underscore is that nothing else begins with this. That lonely leading underscore is a really obvious flag. And this shaves off an extra character. In VS as soon as you type an object-name, and then a period, up pops a sorted list of everything this class has. Type a character, and the list scrolls down to the entries that start with that character.
This is wonderful for efficient coding, but we need to make effective use of it. If you type the letter “m”, that list now scrolls to those members that begin with m. This set is not as exclusive as the set of members that begin with the underscore. Just type the underscore character, and now you’re looking at only the ivars. That is, only your own ivars.  Yeah baby – dats what I’m talkin about.

Uhm.. except, if this is a WPF Window or UserControl, the individual controls that are available to you as ivars will not come up, unless you also named those with beginning underscores. In the interest of keeping those separate, I never do. We have a separate standard for those.

Static class variables:

prefix these with an additional “s”, for “static”.
eg.
s_theInstance;
s_database;

Caveat: with this I have some ambivalence and have seen (and used) the practice of simply using an underscore, and – honestly, I haven’t seen it cause any confusion. The thinking is, we don’t want to overload with syntactic sugar, but you may want to flag these as static in a visually obvious way. In your code reviews, you may want the fact that they’re static to stand out. We catch errors that way. On the other hand, the standard of simply beginning all fields with the underscore – is compelling. Thus, this is a choice which is quite fact-specific. Consider what works best for your situation, make a choice, and then stick to it.

Datatypes:

I have in the past preferred to use a limited, common set of prefixes to denote the datatype – where that helps with clarity. Yes, it was a holder from my C++ days, and it serves a similar purpose. And yes — that usefulness is largely gone now, with Intellisense and type safety.

Perhaps it was more just habit. And when intermixing C++ and C#, it did seem nice to have similar formatting. On the other hand, my last contract project strictly avoided this. They (we) used simple camel-cased identifiers with no regard for datatype such as fileName, inputText, and count. Okay. Well, I got used to that. So we have two distinct styles, either of which works fine. After working with both, I have found myself drifting over to not using a strict hungarian-notation style, but with certain code standards yet where it does make sense to preserve clarity.

Yes, Intellisense does reveal the type, but when you’re glancing at a complete program listing, this can help guide your eyes to recognize what you’re seeing.

One of the most common sources of confusion is to use a common name for a variable, when it’s actually something more involved – and you can’t immediately tell by it’s usage. For example, _Identifier; Is that a number, a string, or some other type?  Or outputFile. Is that a stream, or what? If it is a string denoting the pathname of the file, I would name it outputFilePathname, for example.

So. Here is a table of the basic type prefixes to use, IF you happen to be using type prefixes:

Datetype: Standard Prefix: Example:
String: s sMessageText
StringBuilder: sb sbMessage
Boolean: is, has
isFirstTimeThrough
Byte: by byTypeOfService
Integer: i _iRow
Double or Floating-point: f _fElapsedTime
DateTime: dt, or when _whenEntered
Rectangle: rect rectClientArea
Point: pt _ptMouseDown

I don’t suggest using these religiously. Just where it makes sense for clarity. Yes, with auto-typecasting in C# and Intellisense, it’s not as important as before. But I think that, if you’re going to use this style, this can clarify your code even though it’s not as necessary as in days gone by. When you’re scanning a page of code, you want to be able to focus on the algorithms, on the code correctness, not on trying to pick out what each little identifier is. It can help.

  1. class ClassX
  2. {
  3.     string    _sConceptName;
  4.     int       _iReference;
  5.     bool      _bIsValid;
  6.     bool      _bHasMembers;
  7.     decimal   _fRelevance;
  8.     DateTime  _whenReceived;

For C# class properties, if it’s a boolean property: word it such that it begins with “Is”, or an equivalent such as “Has”, e.g. “IsValid”, “IsUsingAFixedDelta”, “HasAccess”. Other properties should be noun phrases or adjectives, not verbs. These are data, right? But the important thing is to word is as a property, not as an action or something else that is misleading. If it has to do some significant work or access a subsystem to return a value, then change it to a function.

On the other hand, methods do things. So give these verb-phrase names, if that is their main purpose, or else phrase it as an answer to a question if you’re using it like a function. e.g.,

  public void DoTheAction()

or..

  public int NumberOfActionsIn(TaskType task)

Graphic-User-Interface Controls

For GUI controls like a TextBox, it’s better to identify the ivars with a short, standard prefix (“txtLastName”) rather than a suffix (“LastNameTextBox”). Why? Because the range of possible names (“LastName”, for example) is a wide-open universe. No matter how familiar you may think you are with this project, the object you seek could start with almost any letter! The best way to exploit your Intellisense is to have the initial characters narrow it down to a manageable list.

Concept

Idea

Area

Category

..

You often wind up having to scroll through a huge list of possible members, and the .NET classes have lots!

But you usually know whether you’re looking for a Label, or a TextBox, or a Button. It is far faster to simply type (again, in VS): “lbl”, to bring up all the Labels available in this class.

“txt” or “ckbx” may seem a bit cryptic at first, but you’ll quickly get used to them. Why? Because they are fixed. We’ve used these for years. They will become second nature to you.

Yes, the “TextBox” suffix says it loudly and clearly. But perhaps a bit too loudly? Once you get into your code, you know this darn thing is a TextBox. What you’re probably trying to distinguish amongst your ivars, is the semantic content: eg, “txtPassword”, “txtLastName”. You will get quite used to associating that little prefix “txt” with a TextBox. Second nature. Really!

txtName is shorter than NameTextBox, and that prefix flags loudly enough that we’re talking about a TextBox. Because you’re being consistent throughtout your code, right? Promulgate this policy across your development team, and be consistent.

The standard prefixes for GUI controls:

GUI Control Standard Prefix Example
Label lbl lblFirstName
TextBox txt txtFirstName
RichTextBox txtr txtrDescription
TextBlock (WPF) txtblk txtblckNote
Masked-edit or specialized textbox txtm txtmPhoneNumber
Button btn btnClose
Radio-button rb rbResidentialProperty
CheckBox ckbx ckbxMakeVisibleToPublic
ComboBox cb cbCountry
DropDownList ddl ddlCountry
ListBox lb lbFilesIncluded
GroupBox groupbox, or gbx gbxName
Panel panel panelWeather
Grid (WPF) grid gridForLeftSide
MenuItem mi miFileOpen

Note that although these are all going to be instance-variables of your class or webpage, we don’t use the underscore (“_”) prefix for these. This helps distinquish them from your own instance-variables that your GUI-designer tool didn’t automatically add. Since these all begin with a standard and relatively small set of prefixes, you can find them easily enough with VS’s Intellisense.

Note too that the masked-edit textbox, the RichTextBox, and other variations of a textbox – all begin with “txt”. This helps you to narrow the list down quickly. It’s not always obvious what kind of textbox you’re dealing with. There are lots of custom controls and 3rd-party toolkits. But you generally do know that it’s some kind of a textbox. So just by typing in “txt” — you instantly see all possible candidates. This common prefixing is important!

CheckBox and ComboBox merit careful attention to avoid confusing them. If we used “cbx” for ComboBox, that would be too easy to confuse with “ckbx”. Too close. That extra “k” helps distinquish it.

Name your Buttons with something that describes the action they perform. That is, a verb. Please! What the heck does a btnAnalysis do? btnAnalyze is much clearer. And btnShowAnalysisResults. But not btnResults – this doesn’t make clear whether it generates results, displays it, saves it.. what?

Name your Labels to match the controls they’re associated with, and if they are paired with a TextBox – please, give them the same name. That lblPartName goes with txtPartName is as obvious as you can get.

As a further aid to clarity, I often try to name the label, the textbox, the view-model property, and the domain-model property all the same. For example: lblAge, txtmAge, Age. When you see these using totally distinct terms, for no reason other than that different people authored them — it’s time for some refactoring. Hopefully, your team is having regular get-togethers and devoting a smidgeon of that time to such matters.

I consider this to be one aspect of self-documentation.

Visual-Studio Regions

The expandable regions within VS are a wonderful blessing for you when clarifying your code structure.

They are simple: they group your stuff into named blocks. Check it..

Note this comment format, leading with the triple-slash. VS recognizes this and feeds it into Intellisense, which in turn makes your comment into a tooltip for all your fellow coders to use. It’s awesome!

I strongly suggest you use this format to comment your classes (

    every

class, please!), your class members, and to group all the members into functional groups.

It’s a characteristic of the human mind that we more readily comprehend something that has seven parts or less. In other words, if you have 99 methods, group them into blocks, and group those blocks into larger blocks, until you have no more than 7 top-level blocks. Now, your new programmer can glance at your class, and see only a few regions and know (hopefully) right where to go.

Let’s refine this a bit further..

One way to block them is by syntactic category. In other words, as in the above example – “properties”, “fields”, “methods”, etc. But this really doesn’t give you much. It’s an easy default way of organizing, but it’s usefulness is limited for any but the simplest classes. Another way is to group them into “public interface”, and “internal implementation”. Now the user can go straight to the right region to use your class from without, and ignore the internal implementation details until he needs that.

Caveat: for Windows and UserControls, this doesn’t necessarily contribute much. A Window may have all of it’s functionality defined in terms of private methods, with only it’s constructor being public. Your own usage of it may rely upon sub-classing and overriding it’s protected methods. That doesn’t lend itself to public/private organization. For other classes I do think that a public/private top-level organization is king.

If you have only one method within a category, eliminate that category! (unless it does add valuable additional information). Otherwise you’re simply forcing your user to perform an extra click to expand that region to see what’s inside. The principle is to group into categories in such a way that helps to mentally grasp what all these parts do, yet provide the easiest, fastest possible path for your user (by “user” I mean other developer) to drill down to see what the code actually is.

Another, very useful strategy for breaking your class-members up by region, is by functionality. For example:

event handlers

display control

database access

This is usually more useful for larger classes, as a starting-point. I believe the superior strategy is to break up your regions by major function, not by syntactic category. This especially applies for very large, very complex systems.

Note that I use all lower-case for the region names (except for acronyms). This is a useful way to visually separate the regions that are there just to group things together, from the regions that surround individual methods – where the region-name is the same as the method-name.

It is also very important to use correct grammar in your comments, and to not assume domain-level familiarity on the part of your readers. Spell it out! Say it clearly, as though you’re addressing the line of customers at your local Post Office. This way, when you’re done commenting, you are nearly done documenting.

I appreciate your feedback, criticisms and suggestions for coding standardization. This is important for software engineering and we want our design to be the best possible, right?

Posted in beginner, C#, Software Design, The .NET Framework, The Development Process, WPF | Tagged , , | 2 Comments