This post is a re-examination of some topics I discuss in an older post. This one got long, so I broke into two. I am also going to provide some navigation links:
The Enthusiasm of Discovery
Almost exactly a year ago, I had completed an initial exploration of the Java language, and written a post here in this space about a feature I found attractive in the exception handling mechanism defined by the language. Specifically, I found checked exceptions and the “check or specify” policy associated with them of interest.
That post is here, enthusiastically titled Things to love about Java: Exception Handling. Ok, perhaps I got a little carried away with the title. Also, in my enthusiasm, I had not yet learned enough to authoritatively comment on the subject. Lastly, I confused the entire Checked Exception paradigm with the small piece of it which I found of interest. More on that in a moment.
In the interest of getting some feedback on my observations, I posted a link here in /r/java of Reddit. Apparently, in my naiveté, I had touched on a sore point in the Java community. The very first comment on the post was a good-natured “Well I see a religious war starting here fairly soon.”
“Well I see a religious war starting here fairly soon.”
-Reddit commentor
Soon after this first provocative (but humorous and good-natured) comment, there flowed a wealth of fascinating discussion, as experienced Java devs weighed in, both pro and con on the subject of checked exceptions, and provided a plethora of useful context and information. In considering my responses to some of these, I realized that I had missed my mark in my original article (or, the discussion helped me find it, anyway!).
One very, very helpful tidbit was a link to this article on the Oracle website describing what some of the original thinking was around the checked exception mechanism. This article establishes on paper, at least, an attractive design philosophy, and example cases for the use of checked exceptions.
Cases Made Against the Existing Java Checked Exception Mechanism
Among the discussion points in the Reddit string, the following stand out to me as strong arguments, not necessarily against the Checked Exception architecture itself, but more against the manner it which it has often come to be used in the field:
- Many Java libraries and frameworks (especially/including core Java API’s) don’t use checked exceptions in accordance with the original design philosophy.
- Checked Exceptions are often used in cases which represent programmer error, rather than predictable events which are at times unavoidable, such as network timeouts, or a storage device is damaged or not available.
- Implementation of an existing interface can be problematic if the implementation code requires a checked exception be thrown, and the method definition on the interface does not throw the correct exception.
- Using Checked Exceptions is often equivalent to “passing the buck” to the consumer of your Method, class, or API.
- The reasoning and actual implementation decisions regarding checked and unchecked exceptions are inconsistent, and no clear rules are available.
Cases Made in Favor of the Checked Exception Mechanism
The following points were made in support of the Checked Exception notion. Philosophically, I agree with them all. It sounds like, though, that points 2 and 3 above may come into play more often than they should in actual practice and negate some of these philosophically sound points:
- When methods declare their exceptions, it forces the designer of an API to carefully consider what can go wrong and throw the appropriate exceptions.
- Exceptions, declared as part of a method signature, forces the consumer of an API to anticipate and handle what may go wrong.
- A method signature represents a contract between the caller and the implementer. It defines the arguments required, the return type, and in the case of Java Checked Exceptions, makes the error cases visible. Requiring a consumer to address anticipatable exceptions theoretically should result in a more robust API (points 2 and three from the previous section notwithstanding).
Clearly, there are some good points on either side of this argument, and like in politics, I find myself stuck on the fence. We will examine my thoughts on this in a bit, after we walk through my current understanding of how things were supposed to be.
On Faults and Contingencies - The Way it was Supposed to Be
According to the article referenced in the link above, a central notion to effective usage of the Java exception architecture is the differentiation between Faults and Contingencies:
Contingency An expected condition demanding an alternative response from a method that can be expressed in terms of the method's intended purpose. The caller of the method expects these kinds of conditions and has a strategy for coping with them.Fault
An unplanned condition that prevents a method from achieving its intended purpose that cannot be described without reference to the method's internal implementation.
The article provides a simple example case in which an API defines a processCheck() method. processCheck will either process a check as requested by the client code, or throw one of two exceptions related to the problem domain: StopPaymentException or InsufficientFundsException. These are presented as examples of Contingencies for which any client calling upon this method should be prepared, and therefore, as exemplary models for Checked Exception usage.
The article additionally discusses a third possibility, in which database access, as part of the transaction processing performed by processCheck, utilizes the JDBC API. JDBC throws a single checked exception, SQLException, to report problems with accessing the data store. Therefore, our processCheck method is required to handle SQLException, or pass any such occurrence up the call stack by including SQLException in its throws clause. In this last case, client code is unlikely to have sufficient context to deal appropriately with whatever caused the SQLException (nor, for that matter, is the processCheck method itself) other than gracefully exiting and informing the calling procedure that something went wrong while accessing the database. This last case is an example of a fault.
To my way of thinking, Contingencies usually exist within the problem domain, and in fact client code calling upon an API is more likely to contain an effective strategy for dealing with them than is the API itself. Faults, on the other hand, represent unexpected conditions which, when our equipment and program is working as designed, should not occur at all. Note that I include “program working as designed” in that sentence. Programmer error and code bugs, for me, fall into this category.
A Overly Simple, Hacked Example
So, thinking I have absorbed the thinking put forth in the article, I construct a hasty example structure which extends the example in the article into a bit of pseudo-code. Note, I am not representing this to be good code, and it represents a hack design at best, greatly over-simplified. My objective is to illustrate the exception usage concepts under discussion. First is the CheckingAccountClass:
A silly mockup of the CheckingAccount Class:
public class CheckingAccount
{
private String _accountID;
private double _currentBalance;
private ArrayList<Integer> _stoppedCheckNumbers;
public String getAccountID()
{
return _accountID;
}
public double getCurrentBalance()
{
return _currentBalance;
}
public void setAccountID(String accountID)
{
_accountID = accountID;
}
public void setCurrentBalance(double currentBalance)
{
_currentBalance = currentBalance;
}
public ArrayList<Integer> getStoppedCheckNumbers()
{
if(_stoppedCheckNumbers == null)
{
_stoppedCheckNumbers = new ArrayList<Integer>();
}
return _stoppedCheckNumbers;
}
public double processCheck(Check submitted)
throws InsufficientFundsException, StopPaymentException,
DatabaseAccessException
{
if(_stoppedCheckNumbers.contains(submitted.getCheckNo()))
{
throw new StopPaymentException();
}
double newBalance = _currentBalance - submitted.getAmount();
if(newBalance < 0)
{
throw new InsufficientFundsException(_currentBalance,
submitted.getAmount(),
newBalance);
}
try
{
// <Code to Update Database to reflect current transaction>
}
catch(SQLException e)
{
// <Code to log SQLException details>
/*
* After logging and/or otherwise handling the SQL failure, throw
* an exception more appropriate to the context of the client code,
* which does not care about the details of the data access operation,
* only that the information could not be retrieved.
*/
throw new DatabaseAccessException("Database Error");
}
return newBalance;
}
}
In order to examine this in context, we will also want to look at a usage scenario with some mock client code. In order to do THAT, we also need a Bank class, which:
- Provides a static factory method to access CheckingAccount objects, and;
- Is also subject to the nefarious SQLException while doing so.
- Introduces yet another contingency - what if the account number submitted on a check does not exist? For this eventuality, we define a fourth Contingency Exception: InvalidAccountException.
The Bank Class (with pseudo-code):
public class Bank
{
public static CheckingAccount getCheckingAccount(String AccountID)
throws DatabaseAccessException, InvalidAccountException
{
CheckingAccount account = new CheckingAccount();
try
{
/*
* <Code to retrieve Account data from data store>
*/
if(//no row is returned for AccountID)
{
throw new InvalidAccountException();
}
// Use test data to initialize an account instance:
account.setAccountID("0001 1234 5678");
account.setCurrentBalance(500.25);
account.getStoppedCheckNumbers().add(1000);
}
catch(SQLException e)
{
// <Code to log SQLException details>
/*
* After logging and/or otherwise handling the SQL failure, throw
* an exception more appropriate to the context of the client code,
* which does not care about the details of the data access operation,
* only that the information could not be retrieved.
*/
throw new DatabaseAccessException("Database Error");
}
return account;
}
}
The Bank Class above provides the functionality needed to mock up some client code. I am not going to get all fancy with this, and the overall class structure is NOT what I am here to examine. We will pretend that the void main method used here actually represents some code in the service of a user interface, and see what our Checked Exception-heavy design looks like from the consumption standpoint:
Some Mock Client Code Consuming the Bank and CheckingAccount API’s:
public class MockClientCode
{
/*
* Assume this code is supporting UI operations.
*/
static String SYSTEM_ERROR_MSG_UI = ""
+ "The requested account is unavailable due to a system error. "
+ "Please try again later.";
static String INVALID_ACCOUNT_MSG_UI = ""
+ "The account number provided is invalid. Please try again.";
static String INSUFFICIENT_FUNDS_MSG_UI = ""
+ "There are insufficient funds in the account to process this check.";
static String STOP_PAYMENT_MSG_UI = ""
+ "There is a stop payment order on the check submitted.
+ "The transaction cannot be processed";
public static void main(String args[])
{
// Sample Data:
String accountID = "0001 1234 5678";
int checkNo = 1000;
double checkAmount = 100.00;
// Use test data to initialize a test check instance:
Check customerCheck = new Check(accountID, checkNo, checkAmount);
CheckingAccount customerAccount = null;
double newBalance;
try
{
customerAccount = Bank.getCheckingAccount(customerCheck.getAccountID());
newBalance = customerAccount.processCheck(customerCheck);
// Output transaction result to UI:
System.out.printf("The transaction has been processed. New Balance is: "
+ DecimalFormat.getCurrencyInstance().format(newBalance));
}
catch (DatabaseAccessException e)
{
// Output the message to the user interface:
System.out.println(SYSTEM_ERROR_MSG_UI);
}
catch (InvalidAccountException e)
{
// Output the message to the user interface:
System.out.println(INVALID_ACCOUNT_MSG_UI);
}
catch (InsufficientFundsException e)
{
// Output the message to the user interface:
System.out.println(INSUFFICIENT_FUNDS_MSG_UI);
}
catch (StopPaymentException e)
{
// TODO Auto-generated catch block
System.out.println(STOP_PAYMENT_MSG_UI);
}
}
}
As With Most Things, a Series of Trade-offs
The “design” above (I am using the term very loosely here) works in accordance with the Java Checked Exception mechanism, and specifically addresses most of the concerns discussed in the Oracle article. I included my own embellishment at the point where the SQLException is potentially thrown locally, by way of logging the data-access specifics for examination by the dev team and/or the dba, and throwing a more general contingency-type exception defined for the problem space (DatabaseAccessException) which can then be handled by client code in a proper context (“Sorry, we seem to be experiencing a system outage. Please try again later”).
Upsides:
On the upside, this code makes robust use of the Check-or-Specify policy built in to the Java environment. Code which attempts to call the public processCheck method will be required to handle all three contingency cases:
- The account number submitted on the check is not valid within the system
- There is a Stop Payment order on the check number being processed
- There are not sufficient funds available to cover the withdrawal
- There is a problem accessing account data (for whatever reason)
From an API design standpoint, this could be considered a good thing. Developers who may be utilizing this class as part of a library or framework will know immediately what contingencies they will have to address within their own code.
With respect to the SQLException (a fault, as opposed to a domain contingency), there is very little that can be done about this even at the point where it is first thrown, other than log the details and notify the calling method that there was a problem retrieving the requested data. In my mind, the farther this specific exception is allowed to propagate from its source, the there is even less ability to do anything with the information it contains. So in my example, I use the try . . . catch block to deal with it as best we can, and then propagate a more appropriate contingency exception.
Also, while the wealth of business-logic-related exceptions is a bit strange looking from my C# background, the code in the mocked up client class is actually pretty easy to read, and figure out what is going on.
Downsides:
On the other hand, what should be a (relatively) simple class structure actually introduces a total of FIVE new types into our project:
- The CheckingAccount class itself
- The Bank Class
- Four new exception types:
- InvalidAccountException
- StopPaymentException
- InsufficientFundsException
- DatabaseAccessException
Client code attempting to use our CheckingAccount class must be aware of all four types, which increases the number of dependencies within a client class. While not serious, as a project grows larger, the inflated number of new types created as contingency exceptions may grow large, and the number of dependencies may grow proportionately. All in all, this could substantially increase project complexity. As one Reddit commenter pointed out, one of the problems with implementations of the Checked Exception mechanism in Java is that it results in what is essentially a “shadow type system.” Hard not to disagree, in light of the example Oracle provides us with.
On top of this, the excessive number of catch clauses is almost as bad as introducing a big switch statement.
Also, within the Oracle article, and within this class definition, what we are essentially doing through the use of “contingency exceptions” is using the exception mechanism to address business logic concerns.
John on Google CodeProject
RHMABHT9JGEH
I bumped into a question on StackOverflow this evening that I felt might make a short post. Accompanying code is available at my Github repo.
The guy who posted observed that the standard .net DataGridview control provides a helpful little glyph next to the row which contains the active cell:

The original poster of the question was wondering how he might include a similar glyph to indicate the active column as well. My problem with that is that there already exists an option for an arrow-like glyph in a column header. Unfortunately, THAT glyph, by convention, tends to mean “Click here to sort on this column.”
That does NOT mean that the OP was off-base, though. I can think of many cases where it would be handy to have some sort of reference to the active column in addition to the active row.
Emphasize the Active Column with the DataGridViewColumn.HeaderCell.Style property
One way to approach this is to simply cause the text in the header cell to be bold when the user navigates to a cell within that column. We can create a class which inherits from DataGridView, and take advantage of the CellEnter Event to cause this to happen:

In the following code, we have a member variable which holds a reference to the last active column. In our constructor, we initialize this column object so that when the control is instantiated, the reference is not null.
We also add an event handler to catch the CellEnter event locally. When this event fires, the handler (dgvControl_CellEnter) catches it, and makes a call to our final method, OnColumnFocus. This method accepts a column index as a parameter, and uses the index to identify the new active column. From there, we can use the HeaderCell.Style property to set the font to “bold” for this particular column.
In our constructor, note that we have to make an initial call to the OnColumnFocus method, so that the default starting column will be highlighted when the control is displayed at first. However, we have to check to see if there are actually any columns present first. This is because the Visual Studio Designer needs to be able to draw the empty control when we first place it on a form.
DataGridView: Cause the Active Column Header to Display Bold Text
class dgvControl : DataGridView
{
// hold a reference to the last active column:
private DataGridViewColumn _currentColumn;
public dgvControl() : base()
{
// Add a handler for the cell enter event:
this.CellEnter += new DataGridViewCellEventHandler(dgvControl_CellEnter);
// When the Control is initialized, instantiate the placeholder
// variable as a new object:
_currentColumn = new DataGridViewColumn();
// In case there are no columns added (for the designer):
if (this.Columns.Count > 0)
{
this.OnColumnFocus(0);
}
}
void dgvControl_CellEnter(object sender, DataGridViewCellEventArgs e)
{
this.OnColumnFocus(e.ColumnIndex);
}
void OnColumnFocus(int ColumnIndex)
{
// If the new cell is in the same column, do nothing:
if (ColumnIndex != _currentColumn.Index)
{
// Set up a custom font to represent the current column:
Font selectedFont = new Font(this.Font, FontStyle.Bold);
// Grab a reference to the current column:
var newColumn = this.Columns[ColumnIndex];
// Change the font to indicate status:
newColumn.HeaderCell.Style.Font = selectedFont;
// Set the font of the previous column back to normal:
_currentColumn.HeaderCell.Style.Font = this.Font;
// Set the current column placeholder to refer to the new column:
_currentColumn = newColumn;
}
}
}
What if I want More?
What if we want more than just bold text in the active header? Well, things get trickier. Manipulating the other properties of the HeaderCell Style require setting EnableHeaderVisualStyles to false. This has the unfortunate side effect of flattening out the styling which some from the Windows 7 GUI styles. The slight gradient and color scheme are replaced by a much flatter header. While we could work around this by overriding the OnPaint method (at least to a degree) and implementing our own painting scheme, the impact of the effect is not too disturbing.
For example, we could decide that in addition to bolding the text in the header, we will set the BackColor to a slightly darker gray:

To do this, we need only add three lines of code. First off, in our constructor, we set the EnableHeaderVisualStyles property to false. Next, in our OnColumnFocus method, we set the Style.BackColor property of the new active column to a darker shade of gray, and restore the previous active column to the default (empty) backcolor:
DataGridView: Cause the Active Column Header to Display Bold Text with a Darker Back Color:
class dgvControl : DataGridView
{
// hold a reference to the last active column:
private DataGridViewColumn _currentColumn;
public dgvControl() : base()
{
this.EnableHeadersVisualStyles = false;
// Add a handler for the cell enter event:
this.CellEnter += new DataGridViewCellEventHandler(dgvControl_CellEnter);
// When the Control is initialized, instantiate the placeholder
// variable as a new object:
_currentColumn = new DataGridViewColumn();
// In case there are no columns added (for the designer):
if (this.Columns.Count > 0)
{
this.OnColumnFocus(0);
}
}
void dgvControl_CellEnter(object sender, DataGridViewCellEventArgs e)
{
this.OnColumnFocus(e.ColumnIndex);
}
void OnColumnFocus(int ColumnIndex)
{
// If the new cell is in the same column, do nothing:
if (ColumnIndex != _currentColumn.Index)
{
// Set up a custom font to represent the current column:
Font selectedFont = new Font(this.Font, FontStyle.Bold);
// Grab a reference to the current column:
var newColumn = this.Columns[ColumnIndex];
// Change the font to indicate status:
newColumn.HeaderCell.Style.Font = selectedFont;
// Change the color to a slightly darker shade of gray:
newColumn.HeaderCell.Style.BackColor = Color.LightGray;
// Set the font of the previous column back to normal:
_currentColumn.HeaderCell.Style.Font = this.Font;
// Change the color of the previous column back to the default:
_currentColumn.HeaderCell.Style.BackColor = Color.Empty;
// Set the current column placeholder to refer to the new column:
_currentColumn = newColumn;
}
}
}
There are other options you might explore. In this post, we walked through some very basic ways to provide visual feedback to the user about their location within the DataGridView control.
The source code for this post is available at my Github repo.
CodeProject John on Google
John on Google CodeProject
Let’s face it. Managing date information within the .net framework (or any framework, really . . . Java is not much better) is a pain the the ass. Really. What makes it even worse is managing user data entry of date information. If that isn’t bad enough, there is a definite data type mismatch between the manner in which the .net framework represents date information, and the way relational databases handle dates.
The complete source code for this project (with a silly demo) is available on Github as a VS 2010 solution. Please feel free to fork, and if you make happy improvements, hit me with a pull request. There is plenty of room for improvement.
The Date Time Picker is Not Appropriate for All Situations . . . Because Sometimes, the Date is Unknown . . .
Sometimes we need to provide a means for users to enter a date if they have the information, and/or leave the date empty (null, if you will) until such time as they do. For example, in entering form data for a person, we may or may not know their Date of Birth. Do we really want to require some date, if we don’t know the correct birthdate? If we use the .Net DateTimePicker control, we have to. While there are hacks and workarounds for this, most require some sort of painful validation checking in our code
Never mind that the DateTimePicker is not the preferred data-entry choice for people who know how to tab through fields. Folks who are good, tab through fields, and enter data. When they come to a date field for which they have no data, they skip past it. They do NOT leave the default date there. And the DateTimePicker requires some date to be present. Not to mention the temptation to stop the tab-type-tab workflow by making you pick from a popup calendar.
The .Net/Winforms Masked Textbox Sucks for Date Entry
That’s right. You heard me. Once upon a time, way back in MS Access, there existed a decent masking approach for entering date values into a textbox. MS seems to have tossed this aside, and delivered the lame control we have at our disposal in the .Net Framework. There are probably reasons for this, but I don’t know what they are. If you have tried using the MaskedTextbox control in a .net application for the purpose of masking date entry, you know what I mean. If you haven’t, go try it out. Then come back here, and see if my solution might be of help.
What I Needed for a Project at Work
I have been stuck working with a rather dull database application at work, and what I needed was a means to perform date entry with the following requirements:
- Null Values are allowed and desirable in the Database backend.
- There will be many places where date-entry is performed, across many forms (it is a date-heavy application related to property management), so the date entry control must be easy to toss onto a form and build around, without a bunch of bs validation and string parsing every time.
- Null values are allowed, but other invalid entries are not.
- All date entry will be performed using the USA-centric mm/dd/yyyy format.
- The time component is irrelevant, or will be handled as a separate entry using a different control
- Given entry of a valid date string, a .net DateTime object should be retrieved from the control.
- Only dates between 1900 and 2099 will be recognized as valid.
What I wanted, for this project, and for general use in whatever other context pops up, was a means to allow the typing in of a date into a text box, validation of the result as a valid date, and the ability for the client code to simply retrieve a nullable datetime object.
For the purposes of my project, I have achieved these requirements. The control has flaws to this point, in terms of general use (limiting the acceptable centuries comes immediately to mind), but it is a starting point.
My Solution: The MaskedDateTextbox Control
I set out to replicate the user-facing aspects of the venerable VBA Masking approach found in the MS Access Textbox, and join it with the .net type system such that a text string date representation could be validated, and then returned to the client code in a useful form, even if null was present.
Inheriting From MaskedTextbox
I began by inheriting from the crusty .net MaskedTextBox control. First order of business was to define the mask we would be using for date entry. For my purposes, I needed to get this done fast, and the project I am working on will only ever require dates in the US-style mm/dd/yyyy format, so I opted to basically fix this as the only mask available.
But what about globalization?
As you can see, for this work-specific implementation, I thwart attempts to change to a different mask, because the code to this point depends upon a final output format of mm/dd/yyyy Anything else will require more work. That said, it would be a small issue to adapt the code to utilize a different date format. I didn’t have time to build in the kind of flexibility which would allow the mask, and the required validations and text manipulations, to be variable. But adapting the code to recognize and work with some other format should be a small problem.
In any case, the following code defines a class, MaskedDateTextBox, which inherits from the .net MaskedTextBox. As you can see, I have defined a few private members, a couple event handlers, a constructor overload, and overridden the OnMaskChanged method. Most importantly, I have set the mask and the prompt character to the standard format, using private constants. The mask format 00/00/0000 requires integers where the zero placeholders are, and ignores non-integer entries.
The Beginnings of the MaskedDateTextBox Class:
public class MaskedDateTextBox : MaskedTextBox
{
// Default setting is to require a valid date string before allowing
// the user to navigate away from the control:
public bool _RequireValidEntry = true;
// The default mask is traditional, USA-centric mm/dd/yyyy format.
private const string DEFAULT_MASK = "00/00/0000";
private const char DEFAULT_PROMPT = '_';
// A flag is set when control initialization is complete. This
// will be used to determine if the Mask property of the control
// (inherited from the Base class) can be changed.
private bool _Initialized = false;
public MaskedDateTextBox() : this(true) { }
public MaskedDateTextBox(bool RequireValidEntry = true) : base()
{
// This is the only mask that will work in the current implementation:
this.Mask = DEFAULT_MASK;
this.PromptChar = DEFAULT_PROMPT;
// Handle Events:
this.Enter +=new EventHandler(MaskedDateTextBox_SelectAllOnEnter);
this.PreviewKeyDown +=new PreviewKeyDownEventHandler(MaskedDateBox_PreviewKeyDown);
// prevent further changes to the mask:
_Initialized = true;
}
protected override void OnMaskChanged(EventArgs e)
{
if (_Initialized)
{
throw new NotImplementedException("The Mask is not chageable in this control");
}
}
}
Note the boolean member _IsInitialized. This is set to true immediately after the mask is set in the constructor. From this point forward, attempts by client code to change the mask will fail, and throw a not implemented exception when the OnMaskChanged method is called by the base.
Also note the optional Constructor parameter RequireValidEntry, which is used to set the local member _RequireValidEntry. This matters a little further along. As it is, the constructor parameter defaults to true, even when the default constructor is used. However, there are cases in which one might prefer to handle invalid date entry from the client code, and this parameter (and the member it sets) come into play at that point. More on this in a minute.
Straightening Out The Date
The core of this control, and the reason I needed to build it, are evidenced in the following logic, which examines user input, and attempts to get it into the proper mm/dd/yyyy format. The trick here is that some people may enter 1/1/2012, others may enter 01/01/2012, and still others may try to use 1-1-12. In my mind, all of these should resolve to the same date.
Add this code to the MaskedDateTextBox class:
Correcting Date Text Entry to Match the Standard Format:
void CorrectDateText(MaskedTextBox dateTextBox)
{
// Replace any odd date separators with the mm/dd/yyyy Standard:
Regex rgx = new Regex(@"(\\|-|\.)");
string FormattedDate = rgx.Replace(dateTextBox.Text, @"/");
// Separate the date components as delimited by standard mm/dd/yyyy formatting:
string[] dateComponents = FormattedDate.Split('/');
string month = dateComponents[0].Trim(); ;
string day = dateComponents[1].Trim();
string year = dateComponents[2].Trim();
// We require a two-digit month. If there is only one digit, add a leading zero:
if (month.Length == 1)
month = "0" + month;
// We require a two-digit day. If there is only one digit, add a leading zero:
if (day.Length == 1)
day = "0" + day;
// We require a four-digit year. If there are only two digits, add
// two digits denoting the current century as leading numerals:
if (year.Length == 2)
year = "20" + year;
// Put the date back together again with proper delimiters, and
dateTextBox.Text = month + "/" + day + "/" + year;
}
Note that we pass this method a reference to a MaskedTextBox. I could have accessed the properties of the containing MaskedTextBox class directly, but it seemed cleaner this way. Also, I may decide to extract this method out into its own class (DateStringFormatter?).
OK. So, we will use the previous method from a number of locations. First off, directly, and the user is entering text. We want to force the user’s input into the proper format as they type (for example, if they separate their date parts with dashes instead of slashes). For this, we will handle the PreviewKeyDown Event. Remember, in our constructor, we added a handler for the PreviewKeyDown Event? Now we’re going to handle that event:
Handle User Input as it Happens with PreviewKeyDown Event:
protected virtual void MaskedDateBox_PreviewKeyDown(object sender,
PreviewKeyDownEventArgs e)
{
MaskedTextBox txt = (MaskedTextBox)sender;
// Check for common date delimiting characters. When encountered,
// adjust the text entry for proper date formatting:
if (e.KeyCode == Keys.Divide
|| e.KeyCode == Keys.Oem5
|| e.KeyCode == Keys.OemQuestion
|| e.KeyCode == Keys.OemPeriod
|| e.KeyValue == 190
|| e.KeyValue == 110)
// If any of the above key values are encountered, apply a formatting
// check to the text entered so far, and make adjustments as needed.
this.CorrectDateText(txt);
}
In the above, we test for the various keys which might indicate the wrong sorts of date delimiter inputs. If any of these undesirable characters are found, we make a quick call to our CorrectDateText method, and straighten things out on the fly, so to speak.
Validate the User Input
Next, we want to perform a check when the user navigates away from the control, to be sure that what they have entered is, in fact, a valid date, as well as to perform any additional re-formatting required. We need three methods to do this. The OnLeave method, which overrides the same method on the base class, uses the boolean function IsValidDate to see if the string represented in the control is a valid date. If so, the overridden method calls the OnLeave method on the base and allows the user to navigate away from the control. If the date is not valid, then the OnInvalidDateEntry method is executed, which raises the InvalidDateEntered event, and depending upon the state of _RequireValidEntry, returns the user to the control to correct the issue.
Testing for a Valid Date Entry Before Leaving the Control
bool IsValidDate(MaskedTextBox dateTextBox)
{
// Remove delimiters from the text contained in the control.
string DateContents = dateTextBox.Text.Replace("/", "").Trim();
// if no date was entered, we will be left with an empty string
// or whitespace.
if (!string.IsNullOrEmpty(DateContents) && DateContents != "")
{
// Split the original date into components:
string[] dateSoFar = dateTextBox.Text.Split('/');
string month = dateSoFar[0].Trim(); ;
string day = dateSoFar[1].Trim();
string year = dateSoFar[2].Trim();
// If the component values are of the proper length for mm/dd/yyyy formatting:
if (month.Length == 2
&& day.Length == 2
&& year.Length == 4
&& (year.StartsWith("19") || year.StartsWith("20")))
{
// Check to see if the string resolves to a valid date:
DateTime d;
if (!DateTime.TryParse(dateTextBox.Text, out d))
{
// The string did NOT resolve to a valid date:
return false;
}
else
// The string resolved to a valid date:
return true;
}
else
{
// The Components are not of the correct size, and automatic adjustment
// is unsuccessful:
return false;
} // End if Components are correctly sized
}
else
// The date string is empty or whitespace - no date is a valid return:
return true;
}
protected override void OnLeave(EventArgs e)
{
// Perform a final adjustment of the text entry to fit the mm/dd/yyyy format:
this.CorrectDateText(this);
// If the entry is a valid date, fire the leave event. We are done here.
if (this.IsValidDate(this))
{
base.OnLeave(e);
}
else
{
this.OnInvalidDateEntry(this, new InvalidDateTextEventArgs(this.Text.Trim()));
// if a valid date entry is not required, the user is free to navigate away
// from the control:
if (!_RequireValidEntry)
{
base.OnLeave(e);
}
}
}
protected virtual void OnInvalidDateEntry(object sender, InvalidDateTextEventArgs e)
{
if (_RequireValidEntry)
{
// Force the user to address the problem before
// navigating away from the control:
MessageBox.Show(e.Message);
this.Focus();
this.MaskedDateTextBox_SelectAllOnEnter(this, new EventArgs());
}
// Raise the invalid entry event either way. Client code can determine
// if and how invalid entry should be dealt with:
if (InvalidDateEntered != null)
{
InvalidDateEntered(this, e);
}
}
Define a Custom Event Handler: InvalidDateTextEventArgs
We hooked up the InvalideDateEntered event in our constructor. However, I defined a custom EventArgs class which is required by the InvalidDateEntered Event. Define the following class in a separate code file:
A Custom EventArgs Class: InvalidDateTextEventArgs
using System;
namespace MaskedDateEntryControl
{
public class InvalidDateTextEventArgs : EventArgs
{
private string _Message = ""
+ "Text does not resolve to a valid date. "
+ "Enter a date in mm/dd/yyyy format, "
+ "or clear the text to represent an empty date.";
private string _InvalidDateString = "";
public InvalidDateTextEventArgs(string InvalidDateString) : base()
{
_InvalidDateString = InvalidDateString;
}
public InvalidDateTextEventArgs(string InvalidDateString, string Message)
: this(InvalidDateString)
{
_Message = Message;
}
public String Message
{
get { return _Message; }
set { _Message = value; }
}
public String InvalidDateString
{
get { return _InvalidDateString; }
}
}
}
Return a Nullable DateTime Object
Ok. Remember one of my requirements was the ability to retrieve a DateTime object (or null) directly from the MaskedDateTextBox control? This next bit of code is where we do that. Add this code to the MaskedDateTextBox control right after the OnInvalidDateEntry method:
A Property Which Returns a Nullable DateTime Object Based on User Input:
public DateTime? DateValue
{
get
{
DateTime d;
DateTime? Result = null;
if (DateTime.TryParse(this.Text, out d))
{
Result = d;
}
return Result;
}
set
{
string DateString = "";
if (value.HasValue)
DateString = value.Value.ToString("MM/dd/yyyy");
this.Text = DateString;
}
}
Using BeginInvoke to Overcome a Deficiency in the .Net MaskedTextBox Control:
So, the thing which was driving me crazy about this control (and the .net MaskedTextBox from which it derives) was that there did NOT seem to be a way to cause the text in the control to be selected upon entry, such as when an invalid string was entered, and the user is returned to the control to fix it. I wanted the complete text existing in the control to be selected at such time as the user enters the control. Unfortunately, there is apparently a bug in the implementation of the MaskedTextBox control which prevents this from happening using the familiar Textbox.Select() method. As it turns out, there is a workaround,which requires the following code:
Use BeginInvoke to Select the Text contained in the MaskedTextBox Control (and derived controls):
void MaskedDateTextBox_SelectAllOnEnter(object sender, EventArgs e)
{
MaskedTextBox m = (MaskedTextBox)sender;
this.BeginInvoke((MethodInvoker)delegate()
{
m.SelectAll();
});
}
In the end, the MaskedDateTextBox as described here provided the solution for the moment. Is this a great control? No. It needs work. There are some limitations resulting from the need to get it done NOW which some design improvements would correct. What could be made better?
- Not restricted to s single date format
- Not restricted to years beginning with 19 and 20
- Probably some refactoring could be done with some of the nested conditionals
You can find the source code for this at my Github repo. Clone the VS2010 project if you want to see the complete code. If you see ways to improve it, please, feel free. If you succeed, hit me up with a pull request - I will happily merge your changes.
CodeProject
Up to this point . . .
This is the third part in a series focused on getting familiar with Git for Windows developers. The series assumes little or no experience using the command line. If you missed the first few posts, here is what we have covered so far:
In the previous post, we learned how to navigate directories within the Windows file system, create new directories, and delete directories. Now let’s look at creating files, and performing rudimentary (VERY rudimentary) text editing from the Bash command prompt.
Before We Proceed . . .
Let’s create a directory to use for the following examples. Open your Bash Command Line Interface (CLI) and make sure you are in your default Windows user folder. Create a new directory within your user folder called BashExcercises, and then move into that directory (Review the previous post if you are unsure how to do this):
Create a Directory for the Following Exercises

Also remember, when we are explaining syntax, we will often use square brackets to denote optional items, and angle brackets to denote use-provided content. In the following:
mkdir [options] <FileName>
We do not type the square brackets or angle brackets. The [options] are, well, optional, meaning there may be none or there may be many, and the <Filename> is required and provided by the user.
Bash: Create/Edit Files (touch/echo)
There are a couple of ways to create a new file using the Bash command prompt. The most basic is the touch command. The purpose of the touch command is ostensibly to change/modify the date/time stamps of files. However, it is commonly used to create new files as well, since, when used without any optional arguments, it does just that: creates a new file, with a date stamp.
Using the Touch Command to Create a New Text File
The syntax for the touch command is
Create a new file with a date stamp:
touch [options] <filename>
There are a number of options for use with the touch command, but for now, we are going to focus on simple file creation, and we won’t be using any of the options. If we want to create a simple text file, we can type:
Create a new Text File Named MyNewTextFile:
$ touch MyNewTextFile.txt
Type the above into your Bash window and hit enter:

Remember from the previous post that in many cases, when a Bash command executes successfully, we are rewarded with simply a new command prompt. However, we can use the ls command we learned from the last post to examine the contents of our directory:

What do you know? There is is. Now, you could open the new file using Notepad (or the text editor of your choosing), but you won’t see much. We have created an empty text file. To open the file using Notepad from the Bash prompt, simply type:
Open MyNewTextFile.txt in Notepad using Bash:
$ notepad MyNewTextFile.txt
Or, of course, you could open the file the old-fashioned way - by double clicking on it with your mouse!
Using the echo Command to Write Strings as Output
Before we look at using echo to create a new file, we should understand a little about what echo DOES.
The primary design purpose of echo is apparently to write strings to the standard output (usually, the Bash CLI).
The syntax for echo is:
Echo Command Syntax:
$ echo [options] <string>
Lets try that now. Type the following into Bash:
Output a line of Text to the Bash Screen:
$ echo show this line on the screen

We can also tell the echo command to write a line of text to a file, using the following syntax:
Syntax: Append text to the end of a file:
$ echo [options] <Text string> >> <FileName>
By using the >> (double right-hand angle-brackets) operator, we tell Bash to append the text to the end of the file. Type the following into the Bash window and hit enter:
$ echo This line was added to the end of the file >> MyNewTextFile.txt

Now, if we use our $ notepad MyNewTextFile.txt Command, we see the following:

Close that window, and let’s add another line. Type the following and hit enter:
Adding Another Line of Text:
$ echo This is another line of text >> MyNewTextFile.txt
The use $ notepad MyNewTextFile.txt again:

Huh. Looks like it worked, kind of. Apparently, Bash isn’t kidding about appending the new text to the end of the file. Happily, we can use the > (a single right-hand angle bracket) operator to replace the text in the current file and get rid of that mess. Type this and hit enter. Then open the file in Notepad again:
Replace the Text in a File with a New Text String:
$ echo This line replaced the old mess > MyNewTextFile.txt
Your Bash window should look like THIS:

And you should see this in your Notepad window:

Use the Echo Command to Create a New File with Text Content:
Ok, back to the original subject - creating a new text file. We can use echo to create a new file, and include the specified text string as content. In fact, it works the same as when we appended or replaced the text in an existing file, because, lacking an option argument telling it not to, Bash will assume that if the file specified in our echo command does not exist, that we want to create one. Type the following and hit enter:
$ echo This is a new line in a new file >> DifferentTextFile.txt
Then use ls -1 to display the directory contents. This is what your Bash window should look like:

Note the presence of our new file. Let’s open it in Notepad, and see what there is to see:

Well, well well. Whadd’ya know!
Bash: Remove Files (rm)
Ok, now lets get rid of our first file. To remove (delete) files using Bash, we use the rm command. The syntax for removing files is as follows;
rm [options] <FileName>
SO now, let’s delete that first file, MyNewTextFile.txt. Type the following, hit enter, then use the ls -1 command to display the directory contents:
rm MyNewTextFile.txt
Your Bash window should look like this:

Remove a Directory and all Contents (rm -rf)
In the previous post, we discussed how to remove an empty directory. But what if we want to remove a direcory and all of its contents? We use the rm command with the -r and -f options:
Syntax for Removing a Directory and All of its Contents:
rm -rf <FolderName>
So now we are going to remove the BashExcercises directory we created at the beginning of this post. Of course, we can’t remove a directory if we are currently IN that directory. So first, let’s return to the directory above (in this case, our home folder) using the cd .. Comand (the cd Command, followed by a single space, followed by two periods in a row. This one means “move up one level”).
Next, type the following into your Bash window, hit enter, and then use the ls -d */ command to view the directories within the current directory (which should be, at this point, your Windows User folder):
$ rm -rf BashExcercises
When you are done, your Bash window should resemble this (note that the directories are organized alphabetically in columns, and the BashExcercises directory is no longer there. Also note that for obvious reasons, your user folder will contain different folders than mine!).

Now, let’s use everything we just learned in this post, plus we’ll add one final tidbit at the end which you may find useful. We’re going to step through this right quick. We will:
- Add one more new directory
- Add a file containing a line of text to the new directory
- Remove the directory and its contents
- Have Bash tell us what was removed.
1. Add a New Directory Named OneLastFolder to our current directory:
$ mkdir OneLastFolder
2. Add a New File Named OneLastFile.txt, containing the text “One more text line” to the new folder:
$ echo One more text line >> OneLastFolder/OneMoreFile.txt
Notice in the above, I did not navigate into the new folder to create the new file, but simply used the relative path from my current location.
3. Remove the directory and all its contents, and have Bash tell us what was done:
rm -rfv OneLastFolder
Notice in the above, I added one more optional argument, the -v option (for “verbose”). This tells Bash to print the actions it took to the output window.
When you have done all of that, your window should look like this:

There you have it. You now have the most basic set of tools for using the Bash Command Line Interface. From here, we are ready to examine the basic command line operations required to start using Git to manage our code. We’ll pick that up in the next post in this series.
Additional Resources:
John on Google
This is the second installment of a multi-part series about getting your feet wet with Git for Windows Developers. If this is your first time here, you may want to review Part I of the series.
If you have been following along so far, you likely have by now installed msysgit on your development machine, and performed the initial configuration necessary to begin using git to track changes in your source code. So, what next?
Well, before we can do much with Git, we need to make sure we have at least a token familiarity with using the Bash command prompt. To do this, we will walk through some basic commands related to navigating in bash, getting information about the file system and environment, and working with directories and files. All of these are necessary in order to work with Git using the Bash command line.
Since these posts can get long (due in large part to the large number of screen shots), this may span a few posts. It’s not as bad as it looks, really. Lots of pictures.
If you are already familiar with the concepts here, and mainly just need help with the proper syntax for performing these actions in Bash, refer to my Basic Git Command Line Reference Post which contains a listing of the most common git and Bash commands without all the narrative.
Otherwise, read on, and let’s get comfortable using the Bash command line in a Windows environment.
Get Acquainted with Bash
The Bash command line comes from a Unix heritage, and even if you are familiar with the Windows command line, or Powershell, using Bash is different.
First, we should get a little comfortable moving around our file system and performing basic tasks with files and directories.
When you first open the Bash command window, you should see something like this:

In the above, the text in green is the User Name and Computer Name, displayed using the convention UserName@ComputerName. The curlicue character following means that we are in our default directory (or folder), usually our Windows User Folder.
A line which begins with the default prompt (in this case, a $ symbol) is a line on which you will enter a command. Lines without the $ symbol will represent feedback from the system. Each time you type in a command and hit enter, Bash will execute the command, return whatever output (if any) and the leave you with a new prompt.
Note that many commands simply execute, and there is no output. It is a principle amongst Linux programming that a good program executes silently, and only provides feedback if requested, or if something has gone wrong. More on this momentarily.
List the Directories within the Current Folder
We can list other directories within our current folder using the ls command. Type ls into your Bash window and hit enter:
Use Bash to list the contents of the current directory:

Huh. That’s a lot of stuff, and except for those items with file extensions, it is hard to tell what is a directory (folder) and what is a file of some sort. Wouldn’t it be nice to show just the folders, without the other stuff?
In a clear case of stating the obvious, the following will clear your Bash window. Type this and hit enter:
Clear the Bash window:
$ clear
Now, let’s try to examine the folders in our current directory again, and see if we can get a more useful view of the subfolders we are working with. Type the following command into the Bash window, and hit enter again:
Print a listing of all directories within the current directory:
$ ls -d */
The result should look like this:

That’s a little more like it. Ok, so now we can see what folders exist within our current directory.
For a cleaner listing of the variations for the ls command, see the Show Directory Contents section of my Basic Git Command Line Reference Post.
Create a New Directory in the Current Directory
Next, let’s create a new folder. The command for creating a new directory is as follows:
Create a new directory within the current directory:
$ mkdir NewFolderName
Type that into your Bash window, substituting MyNewFolder for NewFolderName and hit enter. This is what you should see when you are done:

But hey - nothing happened, right? Wrong.
As mentioned above, when the mkdir command executed properly, the result is “silence.” In other words, Bash assumes YOU know that, lacking additional feedback, everything went fine. Let’s check and see. Type your new “Show me all the folders, but only the folders” command we discussed previously, and hit enter:

Well, what do you know. There is our new folder. But wait. What if we want spaces in the name of our folder? Let’s try THAT with a another new folder. Type the following and hit enter:
Create a folder named My Other New Folder:
$ mkdir My Other New Folder
When you hit enter, you should see something like this:

Hey, looks like everything worked! No complaints from Bash. Let’s see, using our “Show directory contents” command again:

Uh-oh. Looks like things didn’t go quite the way we expected. As it turns out, we confused Bash, because the actual syntax of the mkdir command is:
The full syntax for the mkdir command:
$ mkdir Folder_1 Folder_2 . . . Folder_n
So when we typed in a folder name containing spaces, Bash thought we were creating a separate new folder for each word. As it turns out, most of the time when using Bash, we need to enclose text with spaces in quotes, so that Bash will know that the quoted text represents a single object or idea. Let’s try creating our new folder with spaces in the name again. This time, type the following into the Bash window:
Create a new folder with spaces in the name:
$ mkdir "My Other New Folder"
When you are done, you should see something like this:

Again, we assume that nothing went wrong from a technical standpoint, because Bash executed the command and returned without complaint. If we check to see again, we find the following:

Yay! So now we can not only create folders, but with spaces in the names too, dammit!
For more on creating directories, see the Creating New Directories Section in my Basic Git Command Line Reference Post
Move to a Folder Within the Current Directory
Ok, so now let’s navigate ourselves into the first folder we created, MyNewFolder. First, though, let’s clear the bash window again, so we can get rid of all the clutter we have accumulated so far.
When we want to move to a new location using Bash, we use the cd command:
The correct syntax for this command is:
Change Directory Command Syntax:
$ cd [options] [<DirectoryName>]
In the above, the square brackets denote optional inputs, and the angle brackets denote user-supplied values. In both cases, we do not type the actual brackets into the command window.
Since Bash already knows the current directory we are in, we can specify a folder name which exists in the current directory, without the rest of the directory path. Type the following into the Bash window, and hit enter. You should see something similar to this:

Note in the above that the line above our prompt has changed, and appears to indicate our current path as:
~/MyNewFolder
Remember that Bash uses the ~ symbol to denote our default (User) directory, so this is a relative reference within the user directory. From where we are right now, there are a number of ways we could return to the user directory.
The first is to simply enter the cd command with no additional input. Doing this will return us to the default directory from wherever we happen to be in the file system:
Return to the Default Directory (“Take Me Home”)
$ cd
Another option is to type cd - (that’s the cd command followed by a space, followed by a single dash). This tells bash to go back to the previous directory. In this particular case, the previous directory also happens to be our home user folder, but it really doesn’t matter what directory we came here from, cd - returns us there.
Return to the Previous Directory (“Take Me Back”)
$ cd -
The third option is to type cd .. (that is the cd command, followed by a space, followed by two periods in a row). This command tells bash to go up one level in the folder hierarchy.
Move Up One Level (“Take Me Up”)
$ cd ..
Considering that we are currently in a folder within our home directory, you can see why in the current situation, these three are all about the same in terms of returning to the home directory. At the moment, it is not only the last place we navigated from, but is also one level above our current location. And it is, indeed the home folder. So all three options work for us in this case. Try the “Take Me Up” command. Type it into your Bash window and hit enter. You should see something like this:

Note that we now appear to back in the “directory known as ~” or, our user folder.
Now type the “Take Me Back” Command (cd -) and hit enter:

Now, here we are right back in the MyNewFolder directory. Note that Bash decided to tell us where it took us in long form:
A Linux-Style Directory Path
/c/Users/xivSolutions/MyNewFolder
But wait - what is with that funny directory syntax? That is the Linux directory style. In fact, when typing explicit directory paths into Bash, you will need to use that format, because Bash will not recognize the Windows directory style. It’s easy enough to follow though:
- Instead of using the forward-slash (\) character as a path delimiter, Bash (and Linux) uses the backslash (/)
- /c/ is the Linux way of expressing the familiar C:\
Move to a Specific Directory Using the Complete Directory Path
Knowing this, we can also use explicit paths for navigation. For example, let’s say I wish to move from the current directory to my Documents folder. I can type the following:
Move to a specific directory using the directory path:
$ cd /c/Users/CurrentUserFolder/Documents
Try that now, substituting your user folder, assuming that you have a standard Windows file structure, which includes a Documents folder in your user folder by default:

Ok. If all went well, you should now find yourself in your Documents folder. Note that even though you are within a subfolder of your user folder, Bash is now displaying the long form of the directory path, instead of the shorthand relative path.
Now try using the “Take Me Home” version of the cd command (simply type cd and hit enter):

Presto - back in our home directory.
For more on directory navigation, see the Navigating the File System Section of my Basic Git Command Line Reference Post
Remove Directories
Ok, now what about those folders we “accidentally” created when we entered a multi-part directory name? You know, the folders named “My” and “Other” and “New” and “Folder”? Remember THIS:

Since these folders are all empty, we can simply use the rmdir command:
Remove One or More Empty Directories:
$ rmdir Directory_1 Directory_2 . . . Directory_n
Type the rmdir command as follows and hit enter. When you are done, you should see something like this:

Then, if we check the directory contents again, we see that those extra directories no longer exist:

Removing an empty directory or directories is a simple undertaking. The process is a little different if the directory to be removed contains files or other directories. We’ll look at this in the next post.
Next: Creating and Working with Files using Bash
Additional Resources
Related Posts
John on Google