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

Reply via email to