11
votes

I am trying add a background image using the image property in button. The issue I'm facing is that i can't set StreamImageSource as button background. I encountered the error given below if I try to do so.

The Code I use to set Image:

            ImageSource iconsource =ImageSource.FromStream(() => new MemoryStream(ImgASBytes));
            Button Icon = new Button ();
            Icon.Image = iconsource ;

The Error I encounter:

Error CS0266: Cannot implicitly convert type 'Xamarin.Forms.ImageSource' to 'Xamarin.Forms.FileImageSource'. An explicit conversion exists (are you missing a cast?)

6
The error message tells you that the button expects FileImageSource. Have you tried obeying? - Athari
Yes.. I did.. Image property only accepts file path in string.. And my question is how to cast imagesource to fileimagesource?? - Femil Shajin

6 Answers

13
votes

ImageSource.FromStream () returns a StreamImageSource (see docs). Button.Image accepts only FileImageSource (see docs).

It means that what you're trying to achieve won't work, no matter how hard you try to cast one into the other.

Button.Image will accept images stored as resources in your platform projects, and loaded either with:

Icon.Image = ImageSource.FromFile ("foobar.png");

or

Icon.Image = "foobar.png";
6
votes

The accepted answer is true that you can't cast StreamImageSource to FileImageSource, I think that the real question is about how to share images in a PCL and use them on a button, just like one would when creating an Image forms control.

The answer is to have a Grid which contains both a Button and an Image object, where the Image overlaps the Button.

For example, the C# code might look like this:

ImageSource imageSource = ImageSource.FromStream(() => new MemoryStream(imageAsBytes));

Button iconButton = new Button ();
iconButton.VerticalOptions = LayoutOptions.FillAndExpand;
iconButton.HorizontalOptions = LayoutOptions.FillAndExpand;

var image = new Image();
image.Source = imageSource;
// So it doesn't eat up clicks that should go to the button:
image.InputTransparent = true;
// Give it a margin so it doesn't extend to the edge of the grid
image.Margin = new Thickness(10);

var grid = new Grid();
// If we don't set a width request, it may stretch horizontally in a stack
grid.WidthRequest = 48;
// Add the button first, so it is under the image...
grid.Children.Add(iconButton);
// ...then add the image
grid.Children.Add(image);

You may have to play with the sizes and thickness values but this should get you a clickable button with an icon.

2
votes

As of Xamarin.Forms 3.4.0 you can now use ImageButton. You can use embedded images by using an extension method explained in this MS document

1
votes

Careful with upper- and lowercase in filenames.

I was wondering, why my button-images were shown properly on the simulator, but not on my iPhone.

On the device the filename must match exactly, the simulator doesn't care about upper- and lowercase in filenames.

0
votes

I use this and it works

var imageA = new Image();
imageA.Source=(FileImageSource)ImageSource.FromFile(allergeneLocation)};

or

var imageA = new Image()
{
BackgroundColor = Color.Teal,
Source = (FileImageSource)ImageSource.FromFile(allergeneLocation)},
};
0
votes

Here is what I tried:

Button refreshBut = new Button
        {
            Image = (FileImageSource)
            (ImageSource.FromFile("refreshBut.png"))

        };

While it compiles I then get an unhandled null reference exception with the description: Object reference not set to an instance of an object. I am not sure if this will help anyone else try to solve this but I am at the same wall.