Adding image to a button in WPF C#, image not appearing - c#

I want to create a button in my windows 8 desktop app, which will have an image and a text block. I have to do this using C# coding.
My code is as follows,
Button btn = new Button();
StackPanel btnContentPanel = new StackPanel();
btnContentPanel.Orientation = Orientation.Horizontal;
Image img = new Image();
img.Source = new BitmapImage(newUri(#"C:\Users\Desktop\Images\download.jpg"));
img.Stretch = Stretch.Uniform;
btnContentPanel.Children.Add(img);
TextBlock txBlock = new TextBlock();
txBlock.Text = "My Button";
btnContentPanel.Children.Add(txBlock);
btn.Content = btnContentPanel;
This is not giving any error but the image is not getting displayed. If I add another text block in place of the image, then its appearing, but not the image.
Am I missing anything ? Please help, thank you.

Try building your button like this:
Button btn= new Button
{
Width = 30,
Height = 30,
Content = new Image
{
Source = new BitmapImage(#"C:\Users\Desktop\Images\download.jpg"))
}
};

In the case of a 'missing' image there are several things to consider:
When Xaml can't locate a resource it might ignore it (when it won't throw a XamlParseException)
The Resource must be properly added and defined:
make sure it exists in your project where expected.
Make sure it is built with your project as a Resource.
(Right click -> Properties -> BuildAction='Resource')
Another thing to try in similar cases, which is also useful for reusing of the image (or any other resource):
Define your Image as a Resource in your Xaml:
<UserCondrol.Resources>
<Image x:Key="MyImage" Source.../>
</UserControl.Resources>
And later use it in your desired control/controls:
<Button Content={StaticResource MyImage} />

Related

how to cast (or convert) an ImageSource to FileImageSource [duplicate]

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?)
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";
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.
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
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.
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)},
};
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.

Render CheckBox to Image for Tile

I want to display one or more CheckBoxes on a tile in my Windows Phone app. This works already for TextBlocks, but with a CheckBox it shows only the Text of the CheckBox and not the Checkmark itself.
This is a sample of my code:
public void CreateTile()
{
StackPanel panel = new StackPanel();
panel.VerticalAlignment = VerticalAlignment.Top;
panel.Margin = new Thickness(7.0, 7.0, 7.0, 0);
panel.Width = 336;
panel.Height = 336;
panel.Orientation = Orientation.Vertical;
// Create and add a CheckBox for each task
foreach (var task in _tasks)
{
TextBlock textBlock = new TextBlock();
textBlock.TextWrapping = TextWrapping.Wrap;
textBlock.Style = App.Current.Resources["PhoneTextLargeStyle"] as Style;
textBlock.Foreground = new SolidColorBrush(Colors.White);
textBlock.Text = task.Text;
CheckBox checkBox = new CheckBox();
checkBox.IsChecked = task.IsDone;
checkBox.Content = textBlock;
panel.Children.Add(checkBox);
}
Grid layoutRoot = new Grid();
layoutRoot.Background = new SolidColorBrush(Colors.Blue);
layoutRoot.Width = 336;
layoutRoot.Height = 336;
layoutRoot.Children.Add(panel);
layoutRoot.Measure(new Size(336, 336));
layoutRoot.Arrange(new Rect(0, 0, 336, 336));
layoutRoot.UpdateLayout();
// Render grid into bitmap
WriteableBitmap bitmap = new WriteableBitmap(336, 336);
bitmap.Render(layoutRoot, null);
bitmap.Invalidate();
// Save background image for tile to isolated storage
Uri backgroundImage = TileHelper.SaveTileImage(bitmap);
}
If I create a tile with a background image created by the method above, the tile will look like this:
As you can see the text is displayed but there is no checkmark/square before the text.
I personally like to use Segoe UI Symbol as the Font Family in such situations. This gives me the flexibility to use Text and Symbols together while not messing around too much with code / images. SUS has great modern icons (or characters if you may call them) that are very much Metroish, I'd say.
Just open up Charmap (Win + R and type in charmap) and in the Font Select -> Segoe UI Symbol. Now you can select any character you like and paste into Visual Studio Editor itself. Yes, it works!
The symbol may not display properly in the Editor itself but it will at Runtime
Here are some suggestions:
Here are the corresponding characters:
☑

✅

Don't worry about them not looking right HERE. They should when you follow the above steps.
You can always "hack" it by using images of checkbox controls. Did you try to show created control in UI? i.e. adding it to page? Just to see if your code is executed correctly.
Or another solution would be to use check mark character - http://www.fileformat.info/info/unicode/char/2713/index.htm
I'll try to replicate this problem in my test app since it is strange that it does not work.

Adding Image to wpf

I want to add an Image dynamically to the wpf application.
What I have tried :
Image img = new Image();
img.Height = 100;
img.Width = 100;
img.Visibility = Visibility.Visible;
Thickness th = new Thickness(100, 100, 0, 0);
img.Margin = th;
string strUri2 = String.Format(#"pack://application:,,,/MyFirstWPF;component/Images/tt.jpg");
img.Source = new BitmapImage(new Uri(strUri2));
I know, the image won't display unless I add it to the Content.
this.Content=img;
but with this the existing controls(shapes) on the app are lost.
Now, my question is how to add the image to the content without losing existing controls from the app.
When you are going to load and show an image dynamically, you still need to think about the layout of your application. I would suggest to add an (initially empty) Image control in XAML (for example in a Grid), and later set the Source property of this control in code.
<Grid>
... other controls ...
<Image Name="img" Grid.Row="..." Grid.Column="..."
Width="100" Height="100" Margin="100,100,0,0"/>
</Grid>
Set Source in code:
var uri = new Uri("pack://application:,,,/MyFirstWPF;component/Images/tt.jpg");
img.Source = new BitmapImage(uri);
by default the window content is a grid so try
(this.Content as Grid).Children.Add(img);

Dynamically created button in WPF

I'm try to do a bit of WPF, only really done windows forms until now and not a lot of that...
All I'm trying to do is to dynamically within code (not xaml) set a button to show an image and set the size of the button to auto size to the image.
The code below loads the image but it goes when the mouse is over the button and the button doesn't auto size to the image.
tbButtonPicture contains a local path on the PC to a bitmap e.g. C:\temp\my Artwork\test1.bmp
This what I have thus far which sits inside a loop:
Console.WriteLine(tbButtonPicture);
System.Windows.Controls.Button newBtn = new Button();
//newBtn.Content = i.ToString();
newBtn.Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), tbButtonPicture)));
newBtn.Name = "Button" + i.ToString();
sp.Children.Add(newBtn);
i++;
Wrap your image in an Image control and set this as the button content and you should have your desired effect.
System.Windows.Controls.Button newBtn = new Button();
Image imageControl = new Image();
imageControl.Source = new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), tbButtonPicture));
newBtn.Content = imageControl;
newBtn.Name = "Button" + i.ToString();
sp.Children.Add(newBtn);
i++;
But I totally agree with above comments:
try to solve your issues in xaml its much more easier. Read the suggested resources, they are really helpful.

Creating Images as buttons in code in C# WPF

I want to create an image as a button in code in C# WPF (not a button with BG image but an actual image). I read on this site to use a PictureBox for the image, and I've found that the WPF equivalent is Image. The problem is, that while i've found PictureBox has a .Click that you can set, Image does not. The two things I want to do are:
Create an array of buttons that are images and can be clicked.
Have an image for the unclicked and clicked states of the button.
Is there anything right in front of me I'm missing?
Here is my loop creating the buttons:
sideBarButtons = new Button[infoLoader.categoriesLength];
sideButtons = new Image[infoLoader.categoriesLength];
ImageBrush[] myBg = new ImageBrush[infoLoader.categoriesLength];
for (int i = 0; i < sideBarButtons.Length; i++)
{
myBg[i] = new ImageBrush();
myBg[i].ImageSource = new BitmapImage(graphicLoader.buttonUnselected[(i % myBg.Length)]);
/*sideBarButtons[i] = new Button();
sideBarButtons[i].Content = infoLoader.categories[i].name;
sideBarButtons[i].Background = myBg[i];
//sideBarButtons[i].BorderThickness = ;
sideBarButtons[i].Width = 155;
sideBarButtons[i].Height = 46;
Canvas.SetLeft(sideBarButtons[i], 30);
Canvas.SetTop(sideBarButtons[i], 10 + (46 * i));
sideBarButtons[i].Click += new RoutedEventHandler(this.SideButton_Click);
leftSideBar.Children.Add(sideBarButtons[i]);*/
BitmapImage myBmp = new BitmapImage();
myBmp.BeginInit();
myBmp.UriSource = myBg[i];
myBmp.EndInit();
sideButtons[i] = new Image();
sideButtons[i].Source = myBmp;
sideButtons[i].Width = 155;
sideButtons[i].Height = 46;
Canvas.SetLeft(sideButtons[i], 30);
Canvas.SetTop(sideButtons[i], 10 + (46 * i));
sideButtons[i].Click += new RoutedEventHandler(this.SideButton_Click);
leftSideBar.Children.Add(sideButtons[i]);
}
The first commented out area is when I was creating buttons with buttons and not images, while the second is images and it doesn't work. Thanks in advance.
Two options here:
1.) Instead of using the Click event, which doesn't exist on Image, use MouseDown, which does.
2.) Instead of using Images and repurposing them, use Buttons with a custom style on it. Then you can handle the button's click.
Personally, I'd use the latter, but really either works.

Categories

Resources