Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically changing button icon in WPF

Tags:

c#

button

icons

wpf

I currently have a button, which has an icon/image on it. I have configured the button and image in XAML:

<Button Height="69" HorizontalAlignment="Left" Margin="-2,0,0,0" Name="toggleBroadcast" VerticalAlignment="Top" Width="64" Grid.Row="1" Opacity="0.5" Click="changeBroadcastState_Click">
        <Image Source="Images\playIcon.png" />
</Button>

I need to be able to programmatically change this button's image from playIcon to stopIcon. How can I do this?

like image 691
BSchlinker Avatar asked May 11 '11 22:05

BSchlinker


3 Answers

You can accomplish this by changing the content of the button, through an event handler.

You can set both the "Play" Icon and "Stop" Icon as a resource, under Window.Resources like so:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <Image x:Key="Play" Source="/WpfApplication1;component/Play_Icon.png" Height="50" Width="50" />
    <Image x:Key="Stop" Source="/WpfApplication1;component/Stop_Icon.png" Height="50" Width="50"/>
</Window.Resources>
<Grid>
    <Button Click="Button_Click" Name="MediaButton">
        <DynamicResource ResourceKey="Play"/>
    </Button>
</Grid>

Now, when the button is clicked, you can simply change the button's content to a different resource (the stop icon). In the button's event handler, you can do this:

C#

private void Button_Click(object sender, RoutedEventArgs e)
{
    if (MediaButton.Content == FindResource("Play"))
    {
        MediaButton.Content = FindResource("Stop");
    }
    else
    {
        MediaButton.Content = FindResource("Play");
    }
}

Edit: Shorter notation

MediaButton.Content = FindResource(MediaButton.Content == FindResource("Play") ? "Stop" : "Play");

Hope this helps, let me know if you have any more questions.

like image 54
d.moncada Avatar answered Oct 28 '22 20:10

d.moncada


If you have your image definition something like this:

<Image Source="{Binding ImageSource}" Stretch="Fill"/>

Then in your code where you want to do the switch simply have:

ImageSource = image;

where image is defined as:

image = new BitmapImage(new Uri("/Application;component/Resources/pause.png", UriKind.Relative));

Of course it does rely on you using the MVVM pattern and implementing the INotifyPropertyChanged interface in your code.

like image 38
ChrisF Avatar answered Oct 28 '22 19:10

ChrisF


Use a DataTrigger (edit) in the Image's Style (/edit) on the change condition:

<Button Height="69" HorizontalAlignment="Left" Margin="-2,0,0,0" Name="toggleBroadcast" VerticalAlignment="Top" Width="64" Grid.Row="1" Opacity="0.5" Click="changeBroadcastState_Click">
    <Image>
        <Image.Style>        
            <Style TargetType="{x:Type Image}">
                <Setter Property="Source" Value="Images\playIcon.png" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding myCondition}" Value="True">
                        <Setter Property="Source" Value="Images\stopIcon.png" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Image.Style>        
    </Image>
</Button>

The myCondition variable would then be a boolean property in your ViewModel (or, more general, the Control's DataContext), something like

public bool myCondition { get { return ([whatever that condition might be]); } }

This may also include a setter and could as well be a simple auto property. As with the other MVVM answer, it will rely on the ViewModel to implement INotifyPropertyChanged.

The nice thing is, once the condition is no longer fulfilled, the DataTrigger will automatically set the Source property back to its original value.

Disclaimer: I have no way to test that right now, so take this with a grain of salt and probably some debugging effort...

like image 5
Jan Avatar answered Oct 28 '22 20:10

Jan