Forum Xamarin.Forms

How to get a renderer of a view which is not part of the visual tree?

AlexKeyAlexKey USMember ✭✭
edited March 25 in Xamarin.Forms

It is difficult even to formulate the question right. I’ll try to start from what I’m really trying to achieve but it can be rephrased as “Where the renderer is set for a view?”. That might help me to understand what to do with all that. Or “How to attach a renderer to a view?”.
Ultimately, I want to create a ContentView in the code behind with a bunch of controls inside. For the simplicity of the question let’s say it is going to look like this

            var contentView = new ContentView() {
               Content = new Label() {
                  FontSize = 80d,
                  Text = 2.ToString()
               }
            };

Then, I want to render this view into an image without showing that view. I understand I have to create a dependency service interface and its implementation in the platform specific assembly. It seems to me that approximately this code should work for Android.

         IVisualElementRenderer visualElementRenderer = _View.GetRenderer();

         Bitmap bitmap = Bitmap.CreateBitmap((int)_View.Width, (int)_View.Height, Bitmap.Config.Argb8888);
         var canvas = new Canvas(bitmap);

         visualElementRenderer.View.Draw(canvas);

         var stream = new MemoryStream();
         bitmap.Compress(Bitmap.CompressFormat.Png, 90, stream);
         stream.Seek(0L, SeekOrigin.Begin);

         return ImageSource.FromStream(() => stream);

In the result I will get back an image source which then I should be able to use in the Forms to display an image with this image source.
Now, the big problem is GetRenderer returns null. And it seems it will continue returning null until I add the ContentView to the visual tree. I tried that. After that GetRenderer is not null but even then, it does not become not null immediately when I add ContentView to the visual tree. It becomes not null somewhat later. What I would like to do is to find a way how to initialize the renderer on the ContentView without adding it to the visual tree. Is there a way to set a renderer explicitly and will it work without going through the visual tree? Maybe there is an easy way to generate native controls from the ContentView and render them? What are my options here?

Sign In or Register to comment.