Designing with the Entity Framwork

A number of factors have contributed toward the evolution of the Entity Framework (a technology used to map database entities to objects used within .NET application programs). However, one of the major factors is the way in which developers work. Not all developers work in the same way and not every situation requires the same solution. With this in mind, Microsoft ADO.NET Entity Framework Step by Step helps you understand how the evolution of the Entity Framework has been affected by these factors. It points out how the alternatives provided by the Entity Framework make your job easier by increasing the flexibility of the development environment.

One of the more important evolutionary steps is the inclusion of three modeling techniques within the Entity Framework: Model First (where you create a database based on a model you define), Database First (where you generate a model based on an existing database), and Code First (where you generate a database based on the objects in an existing application without using a designer-based model). You can read about these three models and how they affect your application development in my recent article, “Choosing the Right Entity Framework Workflow.” The purpose of this article is to help you make the best choice in modeling technique for your next Entity Framework project. The article also points out the need to combine techniques at times to obtain a desired result and helps you understand some of the pros/cons of each approach. Of course, there is no wrong or right approach—simply the approach that works best for you.

The Entity Framework is a necessary technology when dealing with the complexities of a large scale development. Modeling tools make it possible to understand complex interactions with greater ease and to explain those interactions to others who might not have development experience. In addition, you use modeling tools to document how objects in an application relate to the tables and other features of a database. Knowledge like this is incredibly important when working in a team environment where team members must communicate well with each other or the project is doomed to failure. Most importantly for the developer, using a modeling technology like the Entity Framework greatly reduces the confusion that can occur when developer moves outside the comfort of a familiar development environment.

Of course, there is a lot more to be said about the Entity Framework and this article (and even my book) are really just a starting point. I always like to get the reader perspective about materials that I write. What are your experiences in using the Entity Framework? Let me know at John@JohnMuellerBooks.com.

 

Review of MCSD Certification Toolkit (Exam 70-483): Programming in C#

You’re really excited about becoming a Microsoft Certified Solutions Developer (MCSD)! How do you proceed to make your venture a success? Having been through several certifications myself, I understand the importance of having a great certification guide to help you overcome some of the less intuitive parts of the examination process. Tiberiu Covaci, Gerry O’Brien, Rod Stephens, and Vincent Varallo have provided such a guide with MCSD Certification Toolkit (Exam 70-483): Programming in C#. Anyone planning to take exam 70-483 will benefit from this book because it presents the exam topics in a highly organized manner.

Let me get one of the gripes out about the book before I discuss all of the good material though. It seems as if every certification guide I’ve ever looked at includes topics such as, “Why Get Certified?” The problem with these topics is that they waste space and bore the reader. The reader already knows why certification is important, so there is no need to discuss the topic. The reasons for getting certified vary, of course, but the vast majority of people can sum it up in one word, money. Certification will open a door to a better job, help the candidate keep an existing job, or move the candidate one step further up the corporate ladder. The topic is unimportant because the only thing the reader wants to know is how to ace the exam (or at least get a passing score). I feel strongly that the authors could have used the space spent in preaching to the choir to provide additional helps and aids. If your tolerance for less useful material is low, then you’ll want to skip directly to page 11 of the book and start reading “How to Study for the Exam Using This Book.”

After you get past Chapter 1, the rest of the book starts to take on a predictable pattern. You read the theory behind each of the topics that the exam will test. Code Labs give you hands on experience putting the theory into practice. My favorite sections are the Real-World Case Scenario, which helps you understand how the theory is actually used to write an application that could exist in the real world. A problem with many certification guides is that they pursue a purely academic course—this book avoids that particular problem and gives you practical knowledge as well.

Each chapter ends with a Chapter Test Questions section that contains a few questions you can use to check what you have absorbed. The questions will typically be useful for one or two uses, so you need to ensure you read the chapter and go through the exercises before you attempt to try the test questions. Otherwise, you won’t really know whether you have absorbed the material. Personally, I found the number of questions a bit small. The authors could have beefed up this section to provide the reader with a better idea of how the exam will appear.

The Cheat Sheet and Review of Key Terms sections provide an outstanding method for refreshing your memory the day before the exam. One of the mistakes I (and probably many others) made in preparing for a certification exam is to study too hard the night before. If you don’t know the material the night before, you most definitely won’t pass the exam because these exams are designed to thwart people who cram. A reminder, an overview of what you should know, is really all you need the night before. Relaxing and getting the rest you need are essential.

I wasn’t quite sure about the Additional Reading and Resources section found in each chapter. This section is helpful, but only if you’re using the book as a reference after the exam, rather than as a means for preparing for the exam. The authors could have possibly skipped this section in favor of providing more questions or other kinds of hands on learning activities (one of my favorite CNE books used puzzles as a learning aid). Then again, having the book as a reference after the example will likely prove useful too—just don’t cloud your mind with too many competing sources of information before the exam. The trick is to keep your mind clear and focused on your objective (passing the exam).

Overall, the text is written in a clear manner and you’ll find that the authors carefully lead you from one topic to the next. Developers who are already familiar with C# application development may find the book a bit boring because it really does cover all the details. The book is more designed for someone who hasn’t programmed using C# in the past. In fact, the authors recommend that more advanced readers simply skim the book and look for areas of weakness, which seems to be a winning strategy.

Of course, the big question is whether a book is worth the price you pay for it. In this case, you’re getting a bargain. The book is well written and will serve the needs of anyone who needs to take the 70-483 exam. Certification usually brings some significant benefit, so anything you spend on materials today will reap financial rewards in the future. Getting a book is also a lot less expensive than taking a course. Using this book will save you money in the long run.

 

Adding a Web Reference in Visual Studio 2010 (Part 2)

Some time ago I provided some step-by-step instructions for creating both a Web Reference and a Service Reference in Visual Studio 2010 in the Adding a Web Reference in Visual Studio 2010 post. In addition, the post explains the difference between the two to make it easier to understand when to use one over the other. The post has proven popular and a number of people have commented on it.

There are a number of questions about the post though and I wanted to answer them in this follow up post. The biggest question is where the WeatherSoapClient class comes from. The WeatherServiceClient() part of the code comes from the way in which Visual Studio interacts with the WSDL. If you look at:

http://www.deeptraining.com/webservices/weather.asmx?WSDL

you find that the WSDL doesn’t contain the word Client either. The WeatherServiceClient class is generated by Visual Studio in response to the WSDL it finds on that site.

 

Another complaint about that original post is that it relies on C#. Just to make things different, this post uses Visual Basic instead. Creating the Service Reference works precisely the same as it does with C#.


To see how this works, go ahead and create a Service Reference as specified in the original post. When you get done creating just the Service Reference, choose View | Class View in Visual Studio. You’ll see a new Class View window open up. Now, drill down into your project. If you create your example using Visual Basic, you’ll see something very similar to this:

WebService011

(The C# view of the dialog box is almost precisely the same.) What you’re seeing here is the result of creating the WeatherService Service Reference. I didn’t do anything else at all to this project. Highlighted in the upper window is the WeatherSoapClient referenced in my article. In the lower window you see the methods associated with that class.

Once you get done, you can recreate the example in Visual Basic. Just add two textboxes (txtCity and txtWeather) and one button (btnTest) to your application. Create an event handler for btnTest. Here’s the code you need to make it work:

Private Sub btnTest_Click(sender As System.Object, _
                          e As System.EventArgs) _
                       Handles btnTest.Click
 
   ' Create an instance of the Web service.
   Dim Client As WeatherService.WeatherSoapClient = _
      New WeatherService.WeatherSoapClient()
 
   ' Query the weather information.
   Dim Output = From ThisData _
      In Client.GetWeather(txtCity.Text) _
      Select ThisData
 
   ' Clear the current information and
   ' output the new information.
   txtWeather.Text = ""
   For Each Letter In Output
      txtWeather.Text = txtWeather.Text + Letter
   Next
End Sub

As you can see, the code is similar to the C# version I provided in the previous post. The point is that you really do need to use the Class View at times to determine how to interact with a Web service after you create either a Web Reference or a Service Reference. My book, LINQ for Dummies, provides a lot more in the way of helpful information on using Web services effectively for queries. If you want a simpler view of Web services using the C# language, check out C# Design and Development instead. Now you know that the names used by other authors don’t come out of thin air either, even though it might seem that way at times. Please let me know if you have any other questions about this example at John@JohnMuellerBooks.com.

 

Exploring the TimeCheck Application (Part 8)

The previous post, Exploring the TimeCheck Application (Part 7), discussed the UserSettings class, which is used to store user settings to the local hard drive. One of the most important settings included in this class is NetworkPath, which points to the location of the group settings and time logs on the network. Using centralized storage makes it possible for an administrator to set the configuration of all systems on the network at once and to also get reports for the activities of all users, even when the target user is offline. Of course, you could always use a local drive for the NetworkPath when you’re the only one working with TimeCheck. No matter where you store the data, the next level of settings are the group settings used to control the overall functionality of the application. These group settings are the target of today’s and next week’s posts.

The first step in this process is to create some classes. The GroupSettings class contains the actual settings you work with. However, to ensure that you can define tasks (the kind of work the user performs) and projects (the client or area of the company that is the client for the work) as you see fit, you also need to create the Project and Task classes. You can create all three classes (GroupSettings, Project, and Task) using the techniques found in Exploring the TimeCheck Application (Part 7).

The Project class is quite simple in this example. All you really need is the name of the project as shown in the following listing.

namespace TimeCheck
{
   // Contains a single standard project name.
   [Serializable()]
   public class Project
   {
      public String Name { get; set; }
   }
}

Notice that this class is marked as [Serializable()], which is a requirement when working with XML storage files. An implementation for a larger organization could include additional information, such as the client contact information. The idea is to create properties that define what a project is to your organization. In my case, all I need is the project name.

The Task class for this example is similarly simple. All it contains is the name of a task that the user might perform, such as word processing or graphics. Here is the source code for this part of the example.

namespace TimeCheck
{
   // Contains a single standard task name.
   [Serializable()]
   public class Task
   {
      public String Name { get; set; }
   }
}

As with the Project class, you must mark the Task class as [Serializable()]. Even though my class contains only the name of the task, you could easily expand this class to include other information, such as a list of work groups that normally perform this task. The use of a class makes it possible to expand the definition of a task as needed to match the requirements of your organization.

In order to start coding the GroupSettings class, you must provide both file and XML support. You need to add the following using statements at the beginning of the file.

// Add these statements to your project for XML support.
using System.Xml;
using System.Xml.Serialization;
 
// Add this statement for file system support.
using System.IO;

Look again at frmConfigure in Exploring the TimeCheck Application (Part 3). The top half of this form relies on the UserSettings class, while the bottom half relies on the GroupSettings class. There are four properties that support the four fields shown in the bottom of frmConfigure as shown here.

// Determines whether custom projects are allowed.
public Boolean CustomProject { get; set; }
 
// Determines whether custom tasks are allowed.
public Boolean CustomTask { get; set; }
 
// Contains the standard list of group projects.
public List<Project> ProjectList { get; set; }
 
// Contains the standard list of group tasks.
public List<Task> TaskList { get; set; }

Notice that the CustomProject and CustomTask properties are simple Boolean values. They never require any error handling because the properties are set using a simple check on the form.

The ProjectList and TaskList properties are a List object of type Project and Task. Using generics solves some problems later in the application and makes the code easier to understand and work with. The example application uses the simplified property setup for these properties as well because the application never does anything with the strings except to display and store them. If the application had processed the strings in some way or the Project or Task classes were more complex, then the properties would have to include some sort of error trapping. Keep this in mind if you decide to enhance the example code in some way.

That’s it for this week. Next week you’ll see how to complete the GroupSettings class. Please let me know if you have any questions about this class or any other part of the TimeCheck application at John@JohnMuellerBooks.com.

 

Exploring the TimeCheck Application (Part 7)

I’m sure a number of you were wondering when I was going to get back to the TimeCheck application (if ever). I always want to be sure that I provide good material for you and things have been hectic this summer. Of course, we were off on vacation for a while, then there was my little equipment failure, and the drought has brought problems of it’s own. Now we’re back to working on this example.

If you’ll remember from the last post, Exploring the TimeCheck Application (Part 6), this application actually manages several databases and they’re in different places. In fact, this example will eventually handle more data situations than any other example I’ve ever written for use as a teaching aid—books simply haven’t offered me enough space to explore this sort of application before. This post will discuss the user settings that were described in Part 6. To start this part of the example, you must add a class to the application using the following steps:

 

  1. Right click the TimeCheck entry in Solution Explorer and choose Add | New Item from the context menu. You’ll see the Add New Item – TimeCheck dialog box shown here.
    TimeCheck0701
  2. Highlight the Class template in the middle pane. You see a description of the purpose for this template in the right pane.
  3. Type UserSettings.cs in the Name field and click Add. Visual Studio adds the new class file for you and creates some basic code for it.


Let’s begin at the top of the new class file you’ve created. In order to support the code for this example, you must add some using statements to the top of the UserSettings class file as shown here.

// Add these statements to your project for XML support.
using System.Xml;
using System.Xml.Serialization;
 
// Add this statement for file system support.
using System.IO;

The user’s settings for this example reside on the user’s hard drive. The application must know where to find the network drive with the group settings. In addition, each user can select a default task and a default project. Consequently, the user settings consist of these three properties.

// Contains the user's project preference.
public String DefaultProject { get; set; }
 
// Contains the user's task preference.
public String DefaultTask { get; set; }
 
// Contains the location of the data on the network.
public String NetworkPath { get; set; }

You don’t need to perform any special checks in this case because the application will perform them automatically and the user won’t be able to enter anything that will crash the application. Using this shortcut method of creating properties works just fine for this part of the example.

The default constructor for any class doesn’t do anything. Yes, C# supplies a constructor because you absolutely must provide one, but it’s useless in this case because you need to initialize the properties. The next step is to create a new default constructor that performs the tasks needed as shown here.

// Create a default constructor.
public UserSettings()
{
   // Create default properties.
   this.DefaultProject = "None";
   this.DefaultTask = "None";
   this.NetworkPath = "None";
}

Now we get to the meat of the class. The class must provide static methods for getting and setting the user settings. These static methods help the application work with existing data more efficiently and reduce the need to create unnecessary objects that simply use memory. The following code shows the static methods used to get and set user settings for this application.

// Obtains the user settings.
public static UserSettings GetUserSettings()
{
   // Define a path to the user settings.
   String UserPath =
      Environment.GetFolderPath(
         Environment.SpecialFolder.ApplicationData) + @"\TimeCheck";
 
   // When the path doesn't exist, the user hasn't been set up to
   // use the application, so you need to exit.
   if (!Directory.Exists(UserPath))
      return null;
 
   // Check for the file.
   if (!File.Exists(UserPath + @"\AppData.Config"))
      return null;
 
   // Create an XML serializer.
   XmlSerializer DataReader = new XmlSerializer(typeof(UserSettings));
 
   // Define a data stream.
   StreamReader Input = new StreamReader(UserPath + @"\AppData.Config");
 
   // Load the settings.
   UserSettings Settings = new UserSettings();
   Settings = (UserSettings)DataReader.Deserialize(Input);
   Input.Close();
 
   // Return the user settings to the caller.
   return Settings;
}
 
public static void SetUserSettings(UserSettings Settings)
{
   // Define a path to the user settings.
   String UserPath =
      Environment.GetFolderPath(
         Environment.SpecialFolder.ApplicationData) + @"\TimeCheck";
 
   // When the path doesn't exist, the user hasn't been set up to
   // use the application, so you need to create the path.
   if (!Directory.Exists(UserPath))
      Directory.CreateDirectory(UserPath);
 
   // Check for the file. If it doesn't exist, create it.
   if (!File.Exists(UserPath + @"\AppData.Config"))
   {
      FileStream NewFile = File.Create(UserPath + @"\AppData.Config");
      NewFile.Close();
   }
 
   // Create an XML serializer.
   XmlSerializer DataWriter = new XmlSerializer(typeof(UserSettings));
 
   // Define a data stream.
   StreamWriter Output = new StreamWriter(UserPath + @"\AppData.Config");
 
   // Load the settings.
   DataWriter.Serialize(Output, Settings);
   Output.Close();
}

In both cases, the code begins by obtaining the location of the user’s data store on the local hard drive by calling Environment.GetFolderPath(). The Environment.SpecialFolder.ApplicationData enumeration contains the location of the root of the data store. This application stores its data in the \TimeCheck subdirectory.

The next step is to ensure that the \TimeCheck subdirectory actually exists and that it contains a file named AppData.Config. When the class is getting the settings, a failure to find either the directory or the file means that there is no data to obtain, so GetUserSettings() returns a value of null. However, when saving the user settings, the SetUserSettings() method must create the required directory and file when it doesn’t exist.

At this point, there is either data to get or data to save. The data is stored in XML format. In order to work with XML data, you create an XmlSerializer to either serialize (change the properties into XML) or deserialize (change the XML into properties) the data. A StreamReader or StreamWriter provides read or write access to the physical file. The code can now serialize the local data to the XML file or deserialize the data from the XML file and store it locally.

Notice that the example is careful to close files immediately after use. Even though it may seem that the application would perform this task automatically, it does so only after you exit the method and may not close it immediately. In the meantime, an application error could potentially cause damage to the data. In addition, if the application must create the AppData.Config file, the application will register an access error when you try to reopen the file for reading.

Well, that’s it for the UserSettings class. Next week will begin looking at the GroupSettings class (which is considerably more complicated than this class was). In the meantime, let me know if you have any questions about this part of the application at John@JohnMuellerBooks.com. You can see the next post in this series at Exploring the TimeCheck Application (Part 8).

 

Entity Framework Programmer Beta Readers Needed

Next week I’ll begin work on my 91st book, “Entity Framework Development Step-by-Step.” This technology is really exciting. Microsoft keeps improving the Entity Framework support and Entity Framework 5 is no exception. Just in case you haven’t seen it, Microsoft recently released the Entity Framework 5 release candidate through NuGet. You can read about the updated technology on the ADO.NET blog.

 

The Entity Framework is an ADO.NET technology that maps a database and its underlying structures to objects that a developer can easily access within application code. Before the Entity Framework, a developer needed to write code that directly accessed to the database, which caused considerable problems every time the database received an update. The Entity Framework helps shield applications from underlying changes in a database. You can read about the Entity Framework in more detail in the Entity Framework Overview provided by Microsoft. Microsoft also provides a support center that offers some basic Entity Framework learning tools.


The Entity Framework is amazing technology because it greatly reduces the work you need to do and even automates many of the processes used to interact with databases. My book will make performing tasks even easier. As you go through the book, you’ll see how to perform many Entity Framework-related tasks using step-by-step procedures. There won’t be any guesswork on your part. As a beta reader, you’ll be able to provide me input on when these procedures work, and when I need to work on them some more to help prevent Errors in Writing.

You may have an Entity Framework book on your bookshelf already. However, if that book is on an older version of the Entity Framework, you really do need to know about the new features that the Entity Framework provides. In addition, my book will highlight these five essential topics:

 


  • Choosing the right workflow: The main reason this topic is important is that the Entity Framework actually supports several different workflows and they’re all useful in different ways and for different projects.

  • Using LINQ to interact with the Entity Framework: LINQ presents the fastest, most efficient, and least troublesome way to perform basic tasks with the Entity Framework. Of course, this book also discusses more complex methods, but making things simple is essential for the overburdened developer today.

  • Working with Table-Valued Functions: This is a new major feature in the Entity Framework 5 that developers have been requesting for years.

  • Complete application health checking: Because you likely work in an enterprise environment, simply discussing exception handling isn’t enough. You also need to know how to deal with other application health issues, such as what to do when an application has concurrency issues or how to address speed problems. An entire part of the book is devoted to the topic of application health because more organizations than ever are paying close attention to this topic now (as evidenced by the large number of books and articles being created on the topic of Application Performance Monitoring, or APM).

  • Entity customization: Yes, Entity Framework automation is quite good and gets better with every release, but as with any other form of automation, it has limits. Automation can only address those issues that the creator of the automation originally envisioned for it. Developers have a habit of coming up with situations that the automation can’t handle, so that’s why the last part of the book discusses this issue to some degree. I’m not going to delve into this topic so deeply that you feel overwhelmed, so my treatment of the topic is unique in that it gives you a useful set of skills without burdening you with topics so complex that the information becomes buried in jargon.

As I said, I’m really excited about this book and would love to have you read it as I write it. Your input is essential to me. Let me know if you’d like to be a beta reader for this book at John@JohnMuellerBooks.com.

 

Exploring the TimeCheck Application (Part 6)

Last week, we examined the last major user interface issue for this application, adding accessibility features so that someone using a keyboard could access all of the options simply by pressing Tab. I received some good feedback on that post. It’s important to me that applications work as well as possible for everyone. This week’s post will start to examine the underlying application source code—starting with the database used to manage the user time entries.

This application will have more database information than either of the two series presented so far (Exploring the GrabAPicture Application and Exploring the TypingBuddy Application). In fact, there are a number of different databases you need to consider before writing even a single line of code. Here are the basics—upcoming posts will examine each database in detail.

 

  • User Settings: Each user will have individual settings that are stored on the local system. For example, a user can choose to select a default project and a default task, making it easy to log into and out of the system each day. The local user settings also contain a pointer to the network drive used to store the group settings and also to store the user’s time entries. The time entries are actually the most important part of the application because they track the user’s daily activities.
  • Group Settings: The group settings control features that affect the group as a whole are are only accessible by the administrator for editing purposes. For example, you use these settings to control whether the group can use custom tasks or custom projects as part of a log entry. If not, the group is required to select one of the default projects and/or tasks. These settings appear in a central location on the network drive. In order to provide default projects and tasks for users, these settings control two sub-databases:
    • Default Projects: This is a list of the default projects that a user can select from.
    • Default Tasks: This is a list of the default tasks that the user can perform on a given project.
  • Individual Time Entries: Every time entry consists of a time, the project selected, and the task performed on that project. Every login and log out sequence comes as a pair of time entries. The first entry logs the user into the project to perform a given task, while the second entry logs the user out of the project. Each user has a single log file based on his or her name.


These databases are all implemented using XML files, as with the previous series examples, because none of them require true relational capabilities. The reports gather information from the various time logs to create an overview of how the individual or the organization as a whole is using the computer.

As part of figuring the databases out, you also need to consider the data storage requirements. Some of the data need not appear on the network drive. In fact, it has to appear on the local drive or the application won’t be able to find the network data location. Other data appears on the network to provide centralized access to it. Here are the storage locations used for the data in this application.

 

  • C:\Users\<User Name>\AppData\Roaming: Contains the user’s settings and the pointer to the network drive location.
  • \\<Server Name>\<Share Name>\TimeCheck\GroupData: Contains the group settings. Only the administrator can read and write this folder. Regular users can only read this folder.
  • \\<Server Name>\<Share Name>\TimeCheck\<Year>\LogFiles: Contains the individual log files. Administrators can read and write any file. However, regular users can only read and write a specific log file.

I had considered using separate files for each project, but this seems unnecessarily cumbersome. Obviously, you may prefer a different log file and folder setup than the one used in the example. The example is extensible so you can modify the locations as needed for your organization. The reason for using a year folder is to make it easier to archive a specific year’s entries when they’re no longer needed.

Now that you have a better idea of how the databases are arranged, we’ll begin looking at the code used to implement them starting with the next post. I’m going to be out of the office until July 17th, so we’ll talk about the next post in this series on the Friday that follows (July 20th). Until that time, please let me know if you have any questions about the databases or where they’re stored at John@JohnMuellerBooks.com. You can see the next post in this series at Exploring the TimeCheck Application (Part 7).

 

Exploring the TimeCheck Application (Part 5)

Someone reported a problem with last week’s post (see Exploring the TimeCheck Application (Part 4)). It seems that frmReportConfigure has an accessibility problem. Even though the form doesn’t have any functionality built into it just yet, you can compile and run the application to see the problem. Try pressing Tab to move between the radio buttons. You’ll find that you can’t use the Tab key to select Project Report or Totals Report when User Report is selected. The same thing happens with the other selections. It’s impossible to use the Tab to move between the radio buttons even though the application is supposed to make each of the radio buttons a tab stop. Now, imagine that the Tab is your only means of navigating the form (or simply that you’re used to using the keyboard and using the mouse is normally too time consuming to meet your needs).

The problem is that pressing Tab after User Report has the focus selects Selected User. Press Tab again and you move to User’s Project, then to User’s Task, and then back to Close. What’s happening? At first I thought a change in tab order (TabIndex property setting) might do the trick, but that’s not the case. Then I thought about making just the radio buttons tab stops by setting the TabStop property on the ComboBox controls to False. However, not only does this break accessibility, but it didn’t solve the radio button problem. In fact, I spent several hours considering various solutions to the problem. None of the configuration changes I made corrected the problem. If someone has a configuration solution to the problem, please write me at John@JohnMuellerBooks.com.

I finally created a coded fix for the problem. When the user presses Tab on the Close button, the focus should always go to User Report. Likewise, when the user presses Tab for an unchecked radio button, the focus should go to the next radio button in line. When a radio button is checked, the focus should go to the controls associated with the radio button, and then move to the next radio button after the last control. With this in mind, I fixed the accessibility issue on this forum using the following code.

private void btnClose_Leave(object sender, EventArgs e)
{
   // Give the User Report radio button focus.
   rbUser.Focus();
}
 
private void rbUser_Leave(object sender, EventArgs e)
{
   // When User Report isn't checked, then give the focus
   // to the Project Report radio button.
   if (!rbUser.Checked)
      rbProject.Focus();
}
 
private void cbUserTask_Leave(object sender, EventArgs e)
{
   // Give the Project Report radio button focus.
   rbProject.Focus();
}
 
private void rbProject_Leave(object sender, EventArgs e)
{
   // When Project Report isn't checked, then give the focus
   // to the Totals Report radio button.
   if (!rbProject.Checked)
      rbTotals.Focus();
}
 
private void cbSelectedProject_Leave(object sender, EventArgs e)
{
   // Give the Totals Report radio button focus.
   rbTotals.Focus();
}

I appreciate readers keeping me on my toes, especially when it comes to accessibility issues. Next week, we’ll move on to building the database elements for this application. In the meantime, don’t be afraid to write with your questions and comments. You can read the next post in this series at Exploring the TimeCheck Application (Part 6).

 

An Update on Microsoft’s New Casablanca Release

A little over a month ago I wrote a post entitled, “Microsoft’s New Casablanca Release” about Microsoft’s newest Casablanca product. Niklas Gustafsson, a member of the Microsoft Visual C++ Team was kind enough to contact me and answer a few questions about this release. I decided that you also need to know the answers to these questions so that you can make an intelligent decision about Casablanca. As a quick recap, Casablanca is a new product that lets C++ developers interact with the cloud using REST.

The first thing Niklas pointed out is that Casablanca isn’t precisely a product—it’s what is termed as an incubation effort, something to see what is possible and will work. Casablanca is early in its life cycle and doesn’t provide either the quality or maturity that a released product would provide. to me, this means that you need to be careful using Casablanca. For the time being, it’s probably an interesting technology to play with, but you probably shouldn’t employ it in your production application because it will change quite a lot.

Even though I use C++ for utilities and low level program (as described in C++ All-In-One Desk Reference For Dummies), Niklas pointed out that many organizations use C++ for larger, line of business applications. In many cases, the reason for using a language like C++ for this purpose is that the organization has already made an investment in C++, so the language is familiar and the organization already has the required resources. I still can’t imagine creating a large scale user application using C++, but I’m also not the one trying to forge ahead in a large organization. It seems to me that using other languages would be simpler and less error prone, but I’m well-versed in using a number of languages, so I have the option of using the best tool for a specific task. In fact, Niklas summarized C++ usage for larger applications in the following points:

 

  • Raw performance
  • Portability
  • It’s what they know

To make his point clearer, Niklas provided me with a link to a whitepaper entitled “C++ and Cloud Computing” that makes a number of points clear. I encourage you to download this whitepaper and give it a read before you make any decisions regarding C++ and the cloud. It certainly helped me envision how someone might use Casablanca a bit better. For example, even a low-level application could need access to an online storage provider in order to access the information it needs. I also hadn’t considered some special areas of program, such as gaming, when I wrote my original post—I was thinking more along the lines of what a business developer would need.

With regard to my question about using REST, rather than SOAP, Niklas pointed out that REST currently enjoys far wider support than SOAP and that it’s simpler to implement. If Casablanca becomes a success, SOAP support could follow. So, at least the team is thinking about SOAP as a future addition.

It’s also important to remember that many organizations are only starting to think about cloud computing, so technologies such as Casablanca are still well ahead of the curve. Sometimes in reading the technical articles online, you get the idea that cloud computing is already well entrenched in the enterprise. The truth is that many enterprises are only now experimenting with the cloud and some will never use the cloud due to regulatory or other concerns.

I was really happy that Niklas took time out to contact me regarding Casablanca. I’ll be taking another look at this technology as the Visual C++ Team works on it and will likely provide you with an update sometime in the future. In the meantime, let me know how your organization is working in the cloud today at John@JohnMuellerBooks.com.

 

Exploring the TimeCheck Application (Part 3)

In the Exploring the TimeCheck Application (Part 2) post, you saw how the main form for this application goes together. When a user clicks Configure, the application displays a configuration dialog. The configuration dialog is special because it displays in one of two different ways. When an administrator is using the application, the dialog box contains a full set of entries that allow complete application configuration for both personal and group settings. When any other user is working with TimeCheck, the dialog box displays only the user’s personal settings. You’ll see how this works later. For now, all you need to know is how to create the initial form, which contains the full set of configuration options as shown here.

TimeCheck0301

Of course, before you can configure the form, you need to add it to the application. The following steps will help you add this form to the application.

 

  1. Right click the project entry in Solution Explorer and choose Add | Windows Form from the context menu. You’ll see the Add New Item dialog box shown here.
    TimeCheck0302
  2. Type frmConfigure in the Name field and click Add. Visual Studio will add the new form to the project for you and automatically open it for editing.


Now that you have a new form to use, it’s time to add the controls. The following table describes how to add the controls to this dialog box.

Control Property Value
Form1 (Name) frmConfigure
  AcceptButton btnOK
  CancelButton btnCancel
  FormBorderStyle FixedDialog
  Size 400, 420
  Text Configure TimeCheck
ToolTip1 (Name) toolTip1
FolderBrowserDialog1 (Name) NetworkSelect
  Description Choose a Network Location
  RootFolder MyComputer
  SelectedPath C:\
Button1 (Name) btnOK
  AccessibleDescription Accept the Configuration Changes
  Location 307, 12
  Size 75, 23
  TabIndex 0
  Text &OK
  ToolTip on toolTip1 Accept the Configuration Changes
Button2 (Name) btnCancel
  AccessibleDescription Exit Without Making Changes
  DialogResult Cancel
  Location 307, 41
  Size 75, 23
  TabIndex 1
  Text &Cancel
  ToolTip on toolTip1 Exit Without Making Changes
Label1 (Name) lblProjectName
  AccessibleDescription Supply the Name of the Project You Work On Most Now
  Location 12, 9
  Size 108, 13
  TabIndex 2
  Text Default &Project Name
  ToolTip on toolTip1 Supply the Name of the Project You Work On Most Now
ComboBox1 (Name) cbProjectName
  DropDownStyle DropDownList
  Location 12, 25
  Size 289, 21
  TabIndex 3
Label2 (Name) lblWorkType
  AccessibleDescription Choose the Type of Task Normally Performed
  Location 12, 49
  Size 142, 13
  TabIndex 4
  Text Default Type of &Work (Task)
  ToolTip on toolTip1 Choose the Type of Task Normally Performed
ComboBox2 (Name) cbWorkType
  DropDownStyle DropDownList
  Location 12, 65
  Size 289, 21
  TabIndex 5
Label3 (Name) lblNetLocation
  AccessibleDescription Location of the Data Files
  Location 12, 89
  Size 91, 13
  TabIndex 6
  Text &Network Location
  ToolTip on toolTip1 Location of the Data Files
TextBox1 (Name) txtNetLocation
  Location 15, 105
  Size 255, 20
  TabIndex 7
Button3 (Name) btnNetSelect
  AccessibleDescription Display a Dialog to Choose the Network Location
  Location 276, 102
  Size 25, 23
  TabIndex 8
  Text
  ToolTip on toolTip1 Display a Dialog to Choose the Network Location
CheckBox1 (Name) chkCustomProject
  AccessibleDescription Determines the Availability of Custom Project Entries
  Location 12, 131
  Size 125, 17
  TabIndex 9
  Text A&llow Custom Project
  ToolTip on toolTip1 Determines the Availability of Custom Project Entries
CheckBox2 (Name) chkCustomWork
  AccessibleDescription Determines the Availability of Custom Work Entries
  Location 12, 154
  Size 151, 17
  TabIndex 10
  Text Allow Custom &Task Entries
  ToolTip on toolTip1 Determines the Availability of Custom Work Entries
Label4 (Name) lblStandardProjects
  AccessibleDescription Contains the List of Predefined Projects
  Location 12, 174
  Size 121, 13
  TabIndex 11
  Text &Standard Project Entries
  ToolTip on toolTip1 Contains the List of Predefined Projects
ListBox1 (Name) lstStandardProjects
  Location 12, 193
  ScrollAlwaysVisible True
  Size 208, 82
  TabIndex 12
Button4 (Name) btnProjAdd
  AccessibleDescription Add a New Project
  Location 226, 193
  Size 75, 23
  TabIndex 13
  Text &Add
  ToolTip on toolTip1 Add a New Project
Button5 (Name) btnProjEdit
  AccessibleDescription Edit a Standard Project
  Location 226, 222
  Size 75, 23
  TabIndex 14
  Text &Edit
  ToolTip on toolTip1 Edit a Standard Project
Button6 (Name) btnProjDelete
  AccessibleDescription Delete a Standard Project
  Location 226, 251
  Size 75, 23
  TabIndex 15
  Text &Delete
  ToolTip on toolTip1 Delete a Standard Project
Label5 (Name) lblStandardTasks
  AccessibleDescription Contains the List of Predefined Tasks
  Location 12, 278
  Size 82, 13
  TabIndex 16
  Text Standard Tas&ks
  ToolTip on toolTip1 Contains the List of Predefined Tasks
ListBox2 (Name) lstStandardTasks
  Location 12, 294
  ScrollAlwaysVisible True
  Size 208, 82
  TabIndex 17
Button7 (Name) btnTaskAdd
  AccessibleDescription Add a Standard Task
  Location 226, 294
  Size 75, 23
  TabIndex 18
  Text &Add
  ToolTip on toolTip1 Add a Standard Task
Button8 (Name) btnTaskEdit
  AccessibleDescription Edit a Standard Task
  Location 226, 323
  Size 75, 23
  TabIndex 19
  Text &Edit
  ToolTip on toolTip1 Edit a Standard Task
Button9 (Name) btnTaskDelete
  AccessibleDescription Delete a Standard Task
  Location 226, 352
  Size 75, 23
  TabIndex 20
  Text &Delete
  ToolTip on toolTip1 Delete a Standard Task

Most of these controls are self-explanatory. For example, if you click OK the application accepts the changes you made. Clicking Cancel will cancel all of the changes you made.

A user can change his/her default project name and task. Otherwise, the settings are changed by the administrator. However, the network path is stored with the user’s local settings. The reason for this is that the application will know the location of the user’s data when it starts, so it can obtain the network path from the user’s data. It won’t know the location of the data on the network, so it can’t obtain the network path as part of the group data. In addition, the network path could be different for each user, so a per-user setting is necessary.

A project entry is an account for a particular project that the user is working on. That project name could be anything from a customer account number to a plain text description of the project. A task entry is a specific task that the user performs on that project. For example, a project might be ABC Corporation Tax Records, while a task entry might be Data Entry. A user will normally perform a specific number of tasks on a particular project.

Next week we’ll look at the dialog boxes used to configure and show reports. Until then, let me know if you have any questions about the setup or use of this dialog box at John@JohnMuellerBooks.com. You can see the next post in this series at Exploring the TimeCheck Application (Part 4).