Go directly to collection item?

R

Ron Bullman

Gerald,

Very long question indeed. I'm assuming that your listBox1 is
System.Windows.Forms.ListBox, then you can access the selected item from C#
like this listBox1.Items[listBox1.SelectedIndex]


Ron
Gerald Lightsey said:
I am doing some work that involves automating MS MapPoint 2002. The
object model is documented in the context of Visual Basic 6.0. A
typical example follows.

'Output first result of find search
Set objFindResults = objApp.ActiveMap.FindAddressResults("One Microsoft
Way", "Redmond", , "WA", , geoCountryUnitedStates)
MsgBox "The first item in the find list is: " _
+ objFindResults.Item(1).Name

FindResults is a collection. In C# I find that the VB6 syntax .Item (1)
is not acceptable nor is [1]. I don't know if it is acceptable in
VB.NET or not.

When MapPoint attempts to locate an input address it returns an
assessment of how well the results in the specified FindResult
collection match the input criteria, (e.g. geoFirstResultGood,
geoAmbiguousResults, geoNoGoodResult). Therefore if a complete and
unambiguous address is input the ResultsQuality property will be
geoFirstResultGood, and I can .

IEnumerator frEnumerator = oFindResults.GetEnumerator();
frEnumerator.MoveNext();
locX = (MapPoint.Location) frEnumerator.Current;
listBox1.Items.Add( locX.Name );
listBox1.SetSelected(0, true );

If one of the other ResultsQuality values is returned I can.

foreach (MapPoint.Location locX in oFindResults)
{
listBox1.Items.Add( locX.Name );
}

If such an address is simply missing a North/South qualifier there will
only be two or three entries in the listBox. On the other hand, If the
address is 100 N Main St, Willburg, MA, 010907 where someone has
misspelled the city name and the Post Office has changed the zip code,
there can be several hundred items listed in listBox1 showing every 100
Main, City and Zip in Massachusetts. I have no problem with the time
required to LOAD the listBox. At this point I want to manually select
from listBox1 the location on which to perform further MapPoint
operations.

The only way I have been able to do this in C# has been to find the
index of the selected item in the listBox and then walk through the
collection AGAIN to reach the location object on which to perform the
further operations.

if ( listBox1.SelectedIndex != -1 )
{
IEnumerator frEnumerator = oFindResults.GetEnumerator();
for ( int stepper = 0; stepper <= listBox1.SelectedIndex; stepper++ )
frEnumerator.MoveNext();
thisLocation = (MapPoint.Location) frEnumerator.Current;
}

For the list containing several hundred items, walking the collection
again takes a perceptible amount of time on a fast CPU. It seems that
when I know the index of the item in the listBox I should be able to go
directly to the item in the collection rather than walking the
collection again. Is there a better way in C# that I have not found?

Gerald
 
G

Gerald Lightsey

I am doing some work that involves automating MS MapPoint 2002. The
object model is documented in the context of Visual Basic 6.0. A
typical example follows.

'Output first result of find search
Set objFindResults = objApp.ActiveMap.FindAddressResults("One Microsoft
Way", "Redmond", , "WA", , geoCountryUnitedStates)
MsgBox "The first item in the find list is: " _
+ objFindResults.Item(1).Name

FindResults is a collection. In C# I find that the VB6 syntax .Item (1)
is not acceptable nor is [1]. I don't know if it is acceptable in
VB.NET or not.

When MapPoint attempts to locate an input address it returns an
assessment of how well the results in the specified FindResult
collection match the input criteria, (e.g. geoFirstResultGood,
geoAmbiguousResults, geoNoGoodResult). Therefore if a complete and
unambiguous address is input the ResultsQuality property will be
geoFirstResultGood, and I can …

IEnumerator frEnumerator = oFindResults.GetEnumerator();
frEnumerator.MoveNext();
locX = (MapPoint.Location) frEnumerator.Current;
listBox1.Items.Add( locX.Name );
listBox1.SetSelected(0, true );

If one of the other ResultsQuality values is returned I can…

foreach (MapPoint.Location locX in oFindResults)
{
listBox1.Items.Add( locX.Name );
}

If such an address is simply missing a North/South qualifier there will
only be two or three entries in the listBox. On the other hand, If the
address is 100 N Main St, Willburg, MA, 010907 where someone has
misspelled the city name and the Post Office has changed the zip code,
there can be several hundred items listed in listBox1 showing every 100
Main, City and Zip in Massachusetts. I have no problem with the time
required to LOAD the listBox. At this point I want to manually select
from listBox1 the location on which to perform further MapPoint
operations.

The only way I have been able to do this in C# has been to find the
index of the selected item in the listBox and then walk through the
collection AGAIN to reach the location object on which to perform the
further operations…

if ( listBox1.SelectedIndex != -1 )
{
IEnumerator frEnumerator = oFindResults.GetEnumerator();
for ( int stepper = 0; stepper <= listBox1.SelectedIndex; stepper++ )
frEnumerator.MoveNext();
thisLocation = (MapPoint.Location) frEnumerator.Current;
}

For the list containing several hundred items, walking the collection
again takes a perceptible amount of time on a fast CPU. It seems that
when I know the index of the item in the listBox I should be able to go
directly to the item in the collection rather than walking the
collection again. Is there a better way in C# that I have not found?

Gerald
 
G

Gerald Lightsey

If I put [listBox1.SelectedIndex] as a substitute for <your help needed
here> or even [0] I get a compiler error that says, "Property, indexer,
or event 'this' is not supported by the language; try directly calling
accessor method 'MapPoint.FindResults.get_item(ref object)' " I
<snip>

Have you tried what the error message 'MapPoint.FindResults.get_item(ref
object)' suggest?

I must confess, I don't know or understand how to do that.

A MapPoint FindResults collection has five properties.
Application
Count
Item* (Default Property)
Parent
ResultsQuality

There is no get_item method in MapPoint that I can find nor is there one
listed in the .NET Framework Class Library that I have found.

Again, MapPoint help gives this example using VB6 syntax...

'Output first result of find search
Set objFindResults = objApp.ActiveMap.FindAddressResults("One
Microsoft Way", "Redmond", , "WA", , geoCountryUnitedStates)
MsgBox "The first item in the find list is: " _
+ objFindResults.Item(1).Name

This all seems straight-forward initially. I program in dBASE and the
following dBASE command works beautifully to access a location item
directly out of a FindResults collection.

locX = oFindResults.Item(listbox1.itemSelected)

It is only when I try to translate the command from VB6 or dBASE to C#
am I unable to get anything that will compile. Trying to handle it like
an array index, (i.e. [1] ), definitely will not work. Using Item(1)
like VB6 and dBASE tells the compiler I am trying to call a method which
it will not accept. Getting an enumerator or foreach both work but it
means I walk the collection once to lay it into a listBox and again
after dereferencing the listBox selected item.

There is supposed to be a new version of MapPoint out next month and I
hope that its documentation will use .NET syntax. Perhaps then it will
be clear how to do what I think I should be able to do in C#. In the
meantime, I just thought that it probably was a common occurrence for C#
programmers to translate VB6 syntax that uses an integer indexer into an
application's collection object such as objFindResults.Item(1). I was
hoping to learn the trick here.

Gerald
 
R

Ron Bullman

Gerald,

Are you using VS.NET? If so, could you check from the object browser if the
get_item is visible. If so, then use it.


Ron
Gerald Lightsey said:
If I put [listBox1.SelectedIndex] as a substitute for <your help needed
here> or even [0] I get a compiler error that says, "Property, indexer,
or event 'this' is not supported by the language; try directly calling
accessor method 'MapPoint.FindResults.get_item(ref object)' " I
<snip>

Have you tried what the error message 'MapPoint.FindResults.get_item(ref
object)' suggest?

I must confess, I don't know or understand how to do that.

A MapPoint FindResults collection has five properties.
Application
Count
Item* (Default Property)
Parent
ResultsQuality

There is no get_item method in MapPoint that I can find nor is there one
listed in the .NET Framework Class Library that I have found.

Again, MapPoint help gives this example using VB6 syntax...

'Output first result of find search
Set objFindResults = objApp.ActiveMap.FindAddressResults("One
Microsoft Way", "Redmond", , "WA", , geoCountryUnitedStates)
MsgBox "The first item in the find list is: " _
+ objFindResults.Item(1).Name

This all seems straight-forward initially. I program in dBASE and the
following dBASE command works beautifully to access a location item
directly out of a FindResults collection.

locX = oFindResults.Item(listbox1.itemSelected)

It is only when I try to translate the command from VB6 or dBASE to C#
am I unable to get anything that will compile. Trying to handle it like
an array index, (i.e. [1] ), definitely will not work. Using Item(1)
like VB6 and dBASE tells the compiler I am trying to call a method which
it will not accept. Getting an enumerator or foreach both work but it
means I walk the collection once to lay it into a listBox and again
after dereferencing the listBox selected item.

There is supposed to be a new version of MapPoint out next month and I
hope that its documentation will use .NET syntax. Perhaps then it will
be clear how to do what I think I should be able to do in C#. In the
meantime, I just thought that it probably was a common occurrence for C#
programmers to translate VB6 syntax that uses an integer indexer into an
application's collection object such as objFindResults.Item(1). I was
hoping to learn the trick here.

Gerald
 
G

Gerald Lightsey

Gerald,

If I put [listBox1.SelectedIndex] as a substitute for <your help needed
here> or even [0] I get a compiler error that says, "Property, indexer,
or event 'this' is not supported by the language; try directly calling
accessor method 'MapPoint.FindResults.get_item(ref object)' " I
<snip>

Have you tried what the error message 'MapPoint.FindResults.get_item(ref
object)' suggest?

I can't find anywhere get_Item() is actually surfaced and I didn't
understand the implications of the error message. But I found a
previous article dated 7/16/03 from Nicholas Paldino to a similar
question that helped.

He said,
quote
The reason this is happening is that the signature of your methods on
the COM server are taking variants by reference, which translates to
object by reference. Because of this, you have to pass in the exact
type when passing ref parameters. To do this, you will want to use:"

// Create a dummy object for the index.
object pobjIndex = 0;

// Reference the item.
iDrs.Item( ref pobjIndex).Item( ref pobjIndex);

endquote

For my particular problem this translated to...

// listBox.SelectedIndex zero based vs Colletions ones based
object lbIndex = listBox1.SelectedIndex +1;
XLocation = (MapPoint.Location) oFindResults.get_Item( ref lbIndex );

This compiles and in operation picks an item out of a large collection
instantly rather than iterating through it.

Thanks for your input.

Gerald
 
R

Ron Bullman

Gerald,

It's good that you managed to solve your problem.

I can't find anywhere get_Item() is actually surfaced and I didn't
With surfaced you mean that it won't show in the object browser? But the
compiler will recognize it! Perhaps the Interop NG could provide more
details if needed.


Ron
 
G

Gerald Lightsey

With surfaced you mean that it won't show in the object browser? But the
compiler will recognize it! Perhaps the Interop NG could provide more
details if needed.

No, get_Item() does not show up in the object browser. I have done a
bit more searching around the documentation and find that property
access method names starting with get_ and put_ are commonly used in
older applications set up for automation.

A MapPoint FindResults collection has a default property named Item
which some languages, (e.g. dBASE which I have used successfully and
VB6), can address directly. Trying to directly address the Item
property in C# results in nothing but compiler failures but get_Item
pops up in a compiler error message as an alternative if one has a clue
what to do with it. I'm happy to have found out how to do specifically
what I wanted and feel I have learned quite a lot in the process.

Again thanks for your input.

Gerald
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top