GetZipCode Package Sample SDK

Discussions related to SoftPro Select user interface development.

Moderator: Phil Barton

Post Reply
JDavis
Posts: 97
Joined: Mon Sep 22, 2008 5:10 pm

GetZipCode Package Sample SDK

Post by JDavis »

In the GetZipCode package sample in the SDK, it shows how to create a package to the fill in the state and city on the Order.Property. This works fine, but in the sample it is hardcoded to the use property[0]. What if it was property[1] that just got changed? How do we determine which property is currently being edited in the order?
jbright

Re: GetZipCode Package Sample SDK

Post by jbright »

JDavis wrote:In the GetZipCode package sample in the SDK, it shows how to create a package to the fill in the state and city on the Order.Property. This works fine, but in the sample it is hardcoded to the use property[0]. What if it was property[1] that just got changed? How do we determine which property is currently being edited in the order?
Unfortunately, the SDK doesn't directly provide the needed functionality, but we can work around this using reflection. Keep in mind that whenever you use reflection against a third-party's tools, you risk losing that functionality whenever you install a different version of the tool. We chose to live with the hardcoded property index of zero in the example instead of using reflection, because it isn't supported or encouraged. Ideally, we'll introduce a proper way to deal with this in a future release. I will enter an RFE for this.

That said... :twisted:

We need to identify the property when the SelectionChanged event is fired by the MonitorSelection service. We can add this logic right beside the code that identifies the selected control's fieldcode is Property.Zip. Here are the additions need to the ZipCodePackage class:

Add a property for the selected property.

Code: Select all

/// <summary>
/// Which property was selected?
/// </summary>
private IProperty SelectedProperty { get; set; }
Modify IMonitorSelection_SelectionChanged so it can identify the selected property and store it for later use when the user changes focus (presses the tab key).

Code: Select all

// We have entered a zip code field.
WasZipSelectedLast = true;

// Store the selected property.
IBindableControl bindableControl = selection[0].SelectedObjects[0] as SoftPro.UI.Base.IBindableControl;
if ( bindableControl != null )
{
	IOrder order = GetActiveOrder();

	object context = bindableControl.Context;

	for ( int propertyIndex = 0; propertyIndex < order.Property.Count; propertyIndex++ )
	{
		IProperty iprop = order.Property[propertyIndex];
		if ( HaveSameID(iprop, context) )
		{
			SelectedProperty = iprop;
		}
	}
}
Add some reflection code to bridge the gap in the SDK. It is relatively low risk, because it only depends on a property named ID, but is not supported by SoftPro.

Code: Select all

// Yuck!
public static bool HaveSameID( object a, object b )
{
	if ( a == null || b == null )
	{
		return false;
	}

	PropertyInfo propertyA = a.GetType().GetProperty("ID", typeof(Guid));
	PropertyInfo propertyB = b.GetType().GetProperty("ID", typeof(Guid));

	return 
		propertyA != null && 
		propertyB != null && 
		// don't need to check return from GetValue for null, because Guid is a valuetype
		propertyA.GetValue(a, null).Equals(propertyB.GetValue(b, null));
}
Now, we just need to modify the selected property instead of the hardcoded first property.

Code: Select all

/// <summary>
/// If the city and state are unset in the current context, lookup values based on the zip code.
/// </summary>
private void LookupCityStateByZipCode( )
{
	try
	{
		// Sanity check
		Debug.Assert(WasZipSelectedLast, "a Zip field was not the last selection");

		if ( !WasZipSelectedLast || SelectedProperty == null )
		{
			return;
		}

		// If the city or state are set, bail out.
		if ( !string.IsNullOrEmpty(SelectedProperty.City) )
		{
			return;
		}

		if ( !string.IsNullOrEmpty(SelectedProperty.State) )
		{
			return;
		}

		// If the zip code is not at least five characters long, bail out.
		string originalZip = SelectedProperty.Zip;
		if ( originalZip == null || originalZip.Length < 5 )
		{
			return;
		}

		// Strip off the +4 part of the zip code.
		string fiveDigitZip = originalZip.ToString().Substring(0, 5);

		int zip;
		try
		{
			zip = Convert.ToInt32(fiveDigitZip);
		}
		catch ( FormatException )
		{
			// Zip code is not a number.  The UI should prevent this.
			return;
		}

		// Finally!  Let's look up the city and state in our table.
		ZipCodeService.CityState cityState = ZipCodeService.LookupCityState(zip);

		if ( cityState == null )
		{
			// Doh!  All that work, and we couldn't find it.
		}
		else
		{
			// Bingo!
			SelectedProperty.City = cityState.City;
			SelectedProperty.State = cityState.State;
		}
	}
	finally
	{
		WasZipSelectedLast = false;
		SelectedProperty = null;
	}
}
Hope this helps. Just try to go easy on the duct tape. :P
JDavis
Posts: 97
Joined: Mon Sep 22, 2008 5:10 pm

Re: GetZipCode Package Sample SDK

Post by JDavis »

Thanks, I think this will work for us. It is very similar to what we found in the CustomLookupTablePackage SDK sample to find which contact you are editing - by comparing the ID of the text box to that of the contact.

Thanks again.
Post Reply