简体   繁体   中英

Programmatically changing button icon in 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?

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.

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.

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...

试试这个代码

window.Icon = BitmapFrame.Create(Application.GetResourceStream(new Uri("LiveJewel.png", UriKind.RelativeOrAbsolute)).Stream);

I used the other answers in this topic to puzzle together the solution I needed for my MVVM application. The code is used to flip the image and tooltip of a toolbar button (Hide/Unhide in this case). It might help you if I put it all together here. First, the declaration of the button in the xaml file:

<Button ToolTip="{Binding ButtonText}">
    <Image Height="32" Width="32" Source="{Binding ButtonImage}"/>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
        <i:CallMethodAction TargetObject="{Binding}" MethodName="HideAction"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

In my ViewModel class, I declared:

private BitmapImage _buttonImage;

public BitmapImage ButtonImage
{
    get { return _buttonImage; }
    set
    {
        _buttonImage = value;
        OnPropertyChanged("ButtonImage");
    }
}

private string _buttonText;

public string ButtonText
{
    get { return _buttonText; }
    set
    {
        _buttonText = value;
        OnPropertyChanged("ButtonText");
    }
}

Here the code for the event handler that changes the button:

public void HideAction()
{
    // Hide the thing you want to hide
    ...

    // Flip the button
    if (ButtonText == "Hide")
    {
        ButtonImage = new BitmapImage(new Uri(@"pack://application:,,,/Resources/Unhide32.png", UriKind.RelativeOrAbsolute));
        ButtonText = "Unhide";
    }
    else
    {
        ButtonImage = new BitmapImage(new Uri(@"pack://application:,,,/Resources/Hide32.png", UriKind.RelativeOrAbsolute));
        ButtonText = "Hide";
    }
}

In the constructor of my ViewModel class I initialize the image and tooltip:

ButtonImage = new BitmapImage(new Uri(@"pack://application:,,,/Resources/Hide32.png", UriKind.RelativeOrAbsolute));
ButtonText = "Hide";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM