Jon, Thanks for the explanation - I thought I was going crazy there. Thatnks for the explanation on the Invoker wrappers as well, I'll put that in a blog in case others find it useful.
----------------- Chris Tacke President OpenNETCF Consulting, LLC > -----Original Message----- > From: monodroid-boun...@lists.ximian.com [mailto:monodroid- > boun...@lists.ximian.com] On Behalf Of Jonathan Pryor > Sent: Wednesday, February 22, 2012 8:29 PM > To: Discussions related to Mono for Android > Subject: Re: [mono-android] FindViewById returning a ViewGroupInvoker > > On Feb 22, 2012, at 10:50 AM, Chris Tacke wrote: > > Later on in my app, I'd like to get hold of this MapView so I can > zoom in on it, but I'm having difficulty. > > > > My first attempt returned null: > > > > var m = > m_layout.FindViewById<MapView>(Resource.Id.DriverMap); > ... > > So I tried this: > > var m = m_layout.FindViewById(Resource.Id.DriverMap); > > This doesn't make sense to me. :-/ > > View.FindViewById<T>(int) is (incorrectly!) this: > > public T FindViewById<T> (int id) > { > object view = this.FindViewById (id); > > return (T)view; > } > > I have no idea why View.FindViewById<T>(int) would return null while > View.FindViewById(int) returns a non-null instance. I'd expect an > InvalidCastException, since FindViewById<T>(int) is calling > FindViewById(int)... > > As I said, that implementation is incorrect. (Thanks for finding the > bug! I fixed Activity but forgot about View...) It will be fixed in the > 4.2 series so that FindViewById<MapView>() will work as expected. In > the mean time... > > > I run this: > > > > var mt = m.GetType().Name; > > > > And I get back "ViewGroupInvoker" > > The problem here is a leaky abstraction: at present, our Java instance > wrapper logic only knows about types from android.jar/Mono.Android.dll, > and MapView isn't in android.jar, so it's not known. So we check the > base type of MapView, find ViewGroup, which we _do_ know about, but > it's abstract. "Fortunately" our plumbing generates "Invoker" types for > abstract types and interfaces, so we construct a ViewGroupInvoker to > hold thew MapView, as a MapView IS-A ViewGroup, and we return the > invoker. > > This still isn't entirely useful to you. The missing part you want/need > is the Extensions.JavaCast<T>() extension method: > > http://androidapi.xamarin.com/?link=M:Android.Runtime.Extensions. > JavaCast{TResult} > > Extensions.JavaCast<T>() is used to traverse (and type-check) the Java > type system when the Mono for Android type system is dealing with > incomplete information. You could thus do: > > MapView m = > m_layout.FindViewById(Resource.Id.DriverMap).JavaCast<MapView>(); > > This would return a (far more useful) MapView instance instead of a > ViewGroupInvoker instance. > > Thanks, > - Jon > > _______________________________________________ > Monodroid mailing list > Monodroid@lists.ximian.com > > UNSUBSCRIBE INFORMATION: > http://lists.ximian.com/mailman/listinfo/monodroid _______________________________________________ Monodroid mailing list Monodroid@lists.ximian.com UNSUBSCRIBE INFORMATION: http://lists.ximian.com/mailman/listinfo/monodroid