Thanks again Tony, solution 2 worked like a charm.
Paul
Well, now that you show more of what it is you're doing,
I'll tell you that I wouldn't go about it in that way, even
if it works.
Before getting into why, first a little tip on custom classes.
In general, events are used primarly by outside consumers,
not by derived types. In most cases, control based classes
have corresponding overridable virtual methods that should
be overridden in derived classes, rather than handling the
corresponding event.
For example, given the events you're using, this would be
considered the officially correct way to handle those same
notifications:
namespace WpfControlLibrary1
{
class LatitutdeTextBox : TextBox
{
protected override void OnTextChanged( TextChangedEventArgs e )
{
// TODO: Add your implementation here
base.OnTextChanged( e );
}
protected override void OnGotFocus( System.Windows.RoutedEventArgs e )
{
// TODO: Add your implementation here
base.OnGotFocus( e );
}
protected override void OnLostFocus( System.Windows.RoutedEventArgs e )
{
// TODO: Add your implementation here
base.OnLostFocus( e );
}
protected override void OnKeyDown( System.Windows.Input.KeyEventArgs e )
{
// TODO: Add your implementation here
base.OnKeyDown( e );
}
}
}
Insofar as what you're doing, while its certainly possible to use a custom
control to get specially-formatted input like a lat/lon, the disadvantage
of doing it that way is a functional dependence on that custom control.
In .NET, you can use data binding and TypeConverters to implement the
functionality your control provides, in a way that allows it to be used by
any control that's capable of data binding to a property.
You can also use TypeConverters without data binding, by calling them
explicitly from a custom control or from any other code for that matter,
because when the conversion functionality is seperated from control(s)
that use it, it can be easily used wherever it's needed.
In other words, I would expose doubles representing lat & lon values as
properties, and then would write custom TypeConverters that handle
the task of converting between the lat/lon strings and doubles, and then
apply the TypeConverter attributes to the properties, which tells the
framework to use those typeconverters to convert user-entered values
to the native data type, like so:
public class MyGeoLocatedObject
{
private double lat;
private double lon;
[TypeConverter(typeof( LatitudeConverter ))]
public Latitude
{
get
{
return lat;
}
set
{
if( value > 360.0 || value < 0.0 )
throw new ArgumentException("Value is not in the required range");
lat = value;
}
}
[TypeConverter(typeof( LongitudeConverter ))]
public Longitude
{
get
{
return lon;
}
set
{
if( value > 180.0 || value < -180.0 )
throw new ArgumentException("Value is not in the required range");
lon = value;
}
}
}
In the above thoeretical example, LatitudeConverter and LongitudeConverter
are custom classes based on TypeConverter, which perform conversion between
strings and doubles. IOW, they would be responsible for parsing the user entered
strings, validating their correctness and converting them to a double representing
the lat or lon. They would also do the opposite (format the double for display in
the same format it is edited).
The advantages of doing it this way are many. For example, you can
assign an instance of the above class (with the two TypeConverters
implemented) to a PropertyGrid, and the property grid will format the
properties the same way they would be formatted by a custom control,
and the user can also edit the values in the grid it the same format,
and the input will be validated and converted to doubles, without your
having to write a single line of code.
Note that in WPF, TypeConverters are supplemented/superceeded
by ValueConverters, and you can specify a data binding along with a
ValueConverter in XAML.
Here's a more concrete example of a TypeConveter for geo location:
http://www.codeproject.com/KB/webforms/TypeConverters.aspx