Set and Change Button Image by Cliciking on it WPF, C# - c#

I've got a class, which holds 8 BitmapImage in an array. The Images are added in the following way in the class constructor:
public SymbolCollection(string[] symbolNames)
{
Symbols = new BitmapImage[8];
for (int i = 0; i < Symbols.Length; i++)
{
Symbols[i] = new BitmapImage();
Symbols[i].BeginInit();
Symbols[i].UriSource = new Uri(#"/Resources/" + symbolNames[i] + ".png", UriKind.Relative);
Symbols[i].EndInit();
}
}
The button's ImageSource are set to the following:
<Button x:Name="buttonPlayer1" HorizontalAlignment="Left" Height="80" Margin="44,387,0,0" VerticalAlignment="Top" Width="80" Click="OnPlayerSymbolClick">
<Button.Template>
<ControlTemplate>
<Image Source="{Binding Content}"/>
</ControlTemplate>
</Button.Template>
</Button>
I tried to set the image to the button in the MainWindow() method and change it in the OnPlayerSymbolClick() method, but the image doesn't even show up:
public MainWindow()
{
this.InitializeComponent();
SetSymbolCollection();
Uri u = symbolCollectionHolder[0].Symbols[0].UriSource;
Debug.WriteLine(u.ToString());
Image i = new Image();
BitmapImage bmp = new BitmapImage();
bmp.UriSource = u;
i.Source = bmp;
buttonPlayer1.Content = i;
}
private void OnPlayerSymbolClick(object sender, RoutedEventArgs e)
{
ImageBrush imagebrush = new ImageBrush();
imagebrush.ImageSource = symbolCollectionHolder[0].Symbols[1];
buttonPlayer1.Background = imagebrush;
buttonPlayer1.Content = imagebrush;
Debug.WriteLine(buttonPlayer1.Background.ToString());
Debug.WriteLine(imagebrush.ImageSource.ToString());
}
The Build Action for the png-s are set to Resource and there's a Resources folder in the project.

When an image resource file is to be loaded into a BitmapImage in code behind, you should use a Resource File Pack URI:
Symbols[i] = new BitmapImage(new Uri(
"pack://application:,,,/Resources/" + symbolNames[i] + ".png"));
Besides that, setting the Content or Background property is pointless when the Button's Template doesn't use these properties.
You probably wanted to write the Template like this:
<Button x:Name="buttonPlayer1" ...>
<Button.Template>
<ControlTemplate TargetType="Button">
<Image Source="{TemplateBinding Content}"/>
</ControlTemplate>
</Button.Template>
</Button>
which would require an ImageSource (or a derived object) as value of the Button's Content.
You could directly pass one of your Symbols:
buttonPlayer1.Content = Symbols[0];

Related

C# working with button when button name is in a list

I have a few button created from a list, I now need to change one of the buttons image.
i am now trying to convert the string to a button.
How do i take the string and turn it in to a button that i can then work with ?
i have tried this:
Button button = (Button)this.FindName("button_" + list[0].ToString());
button.background = brush;
i get an error of Object reference not set to an instance of an object when i call button.background.
EDIT
this is how i have chosen to change the image of my button:
Uri resourceUri = new Uri("led_On.png", UriKind.Relative);
StreamResourceInfo streamInfo = Application.GetResourceStream(resourceUri);
BitmapFrame temp = BitmapFrame.Create(streamInfo.Stream);
var brush = new ImageBrush();
brush.ImageSource = temp;
Button button = (Button)FindName("button_" + list[0].ToString());
button.Background = brush;
i just cant grab the button with the name button_list[0].
One possible solution to change the WPF Button Image on Click event (C#) is listed below:
Listing 1. Changing Button Image on click (XAML)
<Button Name ="button1" Click="button1_Click">
<Button.Template>
<ControlTemplate TargetType="Button">
<Image x:Name="image1">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Images/ContentImage.png" />
</Style>
</Image.Style>
</Image>
</ControlTemplate>
</Button.Template>
</Button>
Listing 2. C# code behind (button1.click event handler)
private void button1_Click(object sender, RoutedEventArgs a)
{
Image _img= button1.Template.FindName("image1", button1) as Image;
Style _imgStyle = new Style { TargetType = typeof(Image) };
_imgStyle.Setters.Add(new Setter(Image.SourceProperty, new BitmapImage(new Uri(#"pack://application:,,,/YourAssemblyName;component//Images/ContentImage1.png"))));
_img.Style = _imgStyle;
}
Pertinent to your code, it could be re-written in a simple form:
StreamResourceInfo _streamInfo =
Application.GetResourceStream(new Uri("led_On.png", UriKind.Relative));
button.Background = (new ImageBrush(){ImageSource=BitmapFrame.Create(_streamInfo.Stream)});
Just make sure that button object is not null (check this statement: "button_" + list[0] - may be just list[0]?)
Hope this may help.

How to put an image in a progress bar programmatically (WPF)

I'm completely new to WPF and I need some help putting an image in my progress bar (programmatically).
I found this (and it works):
<ProgressBar.Template>
<ControlTemplate>
<Grid>
<Image Name="PART_Track" Source="MyImage" Stretch="Fill"/>
<Rectangle Name="PART_Indicator" Fill="BlanchedAlmond" HorizontalAlignment="Left"/>
</Grid>
</ControlTemplate>
</ProgressBar.Template>
I just need some help converting that XAML code to C# code.
This will get you started :
FrameworkElementFactory grid = new FrameworkElementFactory(typeof(Grid));
FrameworkElementFactory image = new FrameworkElementFactory(typeof(Image));
image.Name = "PART_Track";
ImageSource source = new BitmapImage(...); // create it
image.SetValue(Image.SourceProperty, source);
image.SetValue(Image.StretchProperty, Stretch.Fill);
grid.AppendChild(image);
FrameworkElementFactory rectangle = new FrameworkElementFactory(typeof(Rectangle));
rectangle.Name = "PART_Indicator";
rectangle.SetValue(Rectangle.FillProperty, new SolidColorBrush(Colors.BlanchedAlmond));
rectangle.SetValue(Rectangle.HorizontalAlignmentProperty, HorizontalAlignment.Left);
grid.AppendChild(rectangle);
ControlTemplate ct = new ControlTemplate(typeof(ProgressBar));
ct.VisualTree = grid;
MyProgressBar1.Template = ct;

change image doesn't work dynamically with WPF?

I want to change image dynamically on a button. I think I have what is required to find the image. I have som resourcedictionary for the buttons here:
<BitmapImage x:Key="Mark1Empty" UriSource="Marks/Tom1.png"/>
<BitmapImage x:Key="Mark1Chosen" UriSource="Marks/Ny1.png"/>
Then afterwards, I create the button like this in XAML User control:
<Button x:Name="Mark1Button"
Height="30" Width="40" Template="{StaticResource Mark1ButtonTemplate}"
cal:Message.Attach="[Event Click] = [Action SayHello($source, $this)]"/>
The ControlTemplate looks like this:
<ControlTemplate x:Key="Mark1ButtonTemplate" TargetType="{x:Type Button}">
<Image Name="Mark1ButtonImage" Source="{StaticResource Mark1Empty}" />
</ControlTemplate>
After that. In C# code when I press the image. Then it triggers, but the image doesn't change. It is blank after clicking on the image.
public void SayHello(object sender, object kravsource)
{
var selectedButton = sender as Button;
if (selectedButton != null)
{
Image image = (Image)selectedButton.Template.FindName("Mark1ButtonImage", selectedButton);
BitmapImage imagePicker = (BitmapImage)Application.Current.FindResource("Mark1Chosen");
image.Source = new BitmapImage(new Uri(imagePicker.UriSource.ToString(), UriKind.RelativeOrAbsolute));
image.Stretch = Stretch.Uniform;
}
}

Programmatically Creating Image Button in WPF

I want to create a Windows Toolbar (something like RocketDock) which dynamically creates buttons from serialized classes, but I can't figure out how to dynamically set the image.
As an aside, how should a image be serialized (i want to serialize the image with the storage class, instead of loading it from the original png file location each time)?
I found the following code to create a dependency property
public class ImageButton
{
#region Image dependency property
public static readonly DependencyProperty ImageProperty;
public static ImageSource GetImage(DependencyObject obj)
{
return (ImageSource)obj.GetValue(ImageProperty);
}
public static void SetImage(DependencyObject obj, ImageSource value)
{
obj.SetValue(ImageProperty, value);
}
#endregion
static ImageButton()
{
var metadata = new FrameworkPropertyMetadata((ImageSource)null);
ImageProperty = DependencyProperty.RegisterAttached("Image",
typeof(ImageSource),
typeof(ImageButton), metadata);
}
}
And i created a button style to inherit to set the image
<Style x:Key="ImageButton" TargetType="{x:Type Button}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Image Source="{Binding Path=(Extender:ImageButton.Image), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
HorizontalAlignment="Left" Margin="8,0,0,0" Height="16" Width="16" />
<TextBlock Text="{TemplateBinding Content}" HorizontalAlignment="Center" />
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
but I can't figure out how to set the image from code after I create the button
var newButton = new Button();
var style = (Style)FindResource("ImageButton");
newButton.Image does not resolve. Do I need to do something with style.Resources?
EDIT - response to Olli
Thanks, but... Using...
Link link = new Link(#"c:\temp\dev\ClearAllIcon.png");
var newButton = new Button();
newButton.Content = "bloberific";
var style = (Style)FindResource("ImageButton");
ImageButton.SetImage(newButton, link.IconSource);
MainStack.Children.Add(newButton);
where link is defined as
public Link(string iconPath)
{
IconPath = iconPath;
IconSource = new BitmapImage(new Uri(iconPath));
}
the image does not show, though the text does. The button is normal looking.
You did not create a normal dependency property but an attached dependency property. Your newButton instance has no defined property "Image". Therfore you do not have the convenience CLR property getter/setter (see MSDN for details).
The code should look similar to this to set the image source value:
ImageButton.SetImage(newButton, imageSource);
Link link = new Link(#"c:\temp\dev\ClearAllIcon.png");
var newButton = new Button();
newButton.Content = "bloberific";
var style = (Style)FindResource("ImageButton");
ImageButton.SetImage(newButton, link.IconSource);
MainStack.Children.Add(newButton);
you do not use the style variable - is this the problem ?
This worked for me some time ago to create a little game.
var botao = sender as Button;
Image i = new Image();
i.Source= new BitmapImage(new Uri(#"/Resources/x.png", UriKind.RelativeOrAbsolute));
botao.Content = i;

Error Binding ContentControl to Image from Resource Dictionary

<Grid x:Name="ContentGrid">
<Grid.Resources>
<Image x:Key="art" Source="art.png" Stretch="None" />
</Grid.Resources>
<ContentControl Content="{Binding MyImg}" />
</Grid>
public Image MyImg
{
get { return (Image)GetValue(MyImgProperty); }
set { SetValue(MyImgProperty, value); }
}
public static readonly DependencyProperty MyImgProperty =
DependencyProperty.Register("MyImg", typeof(Image), typeof(MainPage), null);
public MainPage()
{
InitializeComponent();
ContentGrid.DataContext = this;
// Works.
MyImg = new Image() { Source = new BitmapImage(new Uri("art.png", UriKind.Relative)), Stretch = Stretch.None };
// Doesn't Work. Exception The parameter is incorrect. ???
MyImg = ContentGrid.Resources["art"] as Image;
}
ContentGrid.Resources["art"] as Image don't reuturn null but an image with the same source as art.png but assigning to the dependency property fails! why?
The second line isn't working because the image that you're referencing--the image in resources--doesn't have the source set up properly. In the first line, the one that works, you are properly setting up a BitmapImage and using a URI to reference the image. Your image in resources does not do that.
Therefore, try replacing your image in resources with this code:
<Image x:Key="art" Stretch="None">
<Image.Source>
<BitmapImage UriSource="art.png" />
</Image.Source>
</Image>

Categories