[英]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:我已经在 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.我需要能够以编程方式将此按钮的图像从 playIcon 更改为 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.Resources
下设置“Play”图标和“Stop”图标作为资源,如下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>
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# 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
定义为:
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. 当然,它依赖于您使用MVVM模式并在代码中实现INotifyPropertyChanged
接口。
Use a DataTrigger (edit) in the Image's Style (/edit) on the change condition: 在更改条件上使用图像样式(/编辑)中的DataTrigger (编辑) :
<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 然后, myCondition
变量将成为ViewModel中的布尔属性(或者更常见的是Control的DataContext),类似于
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. 这也可能包括一个setter,也可能是一个简单的自动财产。 As with the other MVVM answer, it will rely on the ViewModel to implement INotifyPropertyChanged
. 与其他MVVM答案一样,它将依赖ViewModel来实现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. 好处是,一旦条件不再满足,DataTrigger将自动将Source属性设置回其原始值。
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.我使用本主题中的其他答案来拼凑我的 MVVM 应用程序所需的解决方案。 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:首先是xaml文件中按钮的声明:
<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:在我的 ViewModel 类中,我声明:
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:在我的 ViewModel 类的构造函数中,我初始化了图像和工具提示:
ButtonImage = new BitmapImage(new Uri(@"pack://application:,,,/Resources/Hide32.png", UriKind.RelativeOrAbsolute));
ButtonText = "Hide";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.