Программно изменяемый значок кнопки в WPF

В настоящее время у меня есть кнопка, на которой есть значок/изображение. Я сконфигурировал кнопку и изображение в 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>

Мне нужно иметь возможность программно изменить это изображение кнопки с playIcon на stopIcon. Как я могу это сделать?

Ответ 1

Вы можете выполнить это, изменив содержимое кнопки через обработчик событий.

Вы можете установить значок "Воспроизвести" и "Стоп" в качестве ресурса под Window.Resources следующим образом:

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

Теперь, когда кнопка нажата, вы можете просто изменить содержимое кнопки на другой ресурс (значок остановки). В обработчике событий кнопки вы можете сделать это:

С#

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

Изменить: более короткие обозначения

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

Надеюсь, что это поможет, дайте мне знать, если у вас есть еще вопросы.

Ответ 2

Если у вас есть определение изображения примерно так:

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

Тогда в вашем коде, где вы хотите сделать этот переключатель, просто:

ImageSource = image;

где image определяется как:

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

Конечно, вы полагаетесь на то, что используете шаблон MVVM и реализуете интерфейс INotifyPropertyChanged в своем коде.

Ответ 3

Используйте DataTrigger (изменить) в стиле изображения (/edit) в состоянии изменения:

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

Затем переменная myCondition была бы логическим свойством в вашей модели ViewModel (или, более общей, Control DataContext), что-то вроде

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

Это может также включать в себя сеттер и может также быть простым свойством auto. Как и в случае с другим ответом MVVM, он будет полагаться на ViewModel для реализации INotifyPropertyChanged.

Приятно, что после того, как условие больше не будет выполнено, DataTrigger автоматически вернет исходное значение свойства Source.

Отказ от ответственности: у меня нет возможности проверить это прямо сейчас, поэтому возьмите это с солью и, возможно, с некоторой отладкой...

Ответ 4

Попробуйте этот код

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