【问题标题】:Programmatically changing button icon in WPF以编程方式更改 WPF 中的按钮图标
【发布时间】:2011-08-23 16:47:18
【问题描述】:

我目前有一个按钮,上面有一个图标/图像。我已经在 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。我该怎么做?

【问题讨论】:

    标签: c# wpf button icons


    【解决方案1】:

    我使用本主题中的其他答案来拼凑我的 MVVM 应用程序所需的解决方案。该代码用于翻转工具栏按钮的图像和工具提示(在本例中为隐藏/取消隐藏)。如果我把它们放在一起,它可能会对你有所帮助。 一、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>
    

    在我的 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");
        }
    }
    

    这里是更改按钮的事件处理程序的代码:

    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";
        }
    }
    

    在我的 ViewModel 类的构造函数中,我初始化了图像和工具提示:

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

    【讨论】:

      【解决方案2】:

      您可以通过事件处理程序更改按钮的内容来完成此操作。

      您可以在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>
      

      现在,当单击按钮时,您可以简单地将按钮的内容更改为不同的资源(停止图标)。在按钮的事件处理程序中,您可以这样做:

      C#

      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");
      

      希望对您有所帮助,如果您还有其他问题,请告诉我。

      【讨论】:

      • 我立即投票支持包含 C# 代码。我对 DataTriggers / etc 一无所知,所以其他答案(到目前为止)让我感到困惑。
      • 感谢您选择包含 C# 端的示例代码,我能够在 5 分钟内完成这项工作。我对 XAML 一无所知(我想学习——感谢这个问题,我学到了一些东西)并花了大约 1.5 小时研究 DataTrigger 答案的设计方式。感谢您让我的夜晚更轻松......现在我可以享受我生日的最后 1.5 小时 =)
      • 为了让这对我有用,我必须从 XAML 代码中删除 DynamicResource 键。
      【解决方案3】:

      试试这个代码

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

      【讨论】:

        【解决方案4】:

        在图像的样式中使用 DataTrigger (edit) (/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 中的布尔属性(或者,更一般地说,控件的 DataContext),类似于

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

        这也可能包括一个设置器,也可以是一个简单的自动属性。与其他 MVVM 答案一样,它将依赖 ViewModel 来实现 INotifyPropertyChanged

        好消息是,一旦条件不再满足,DataTrigger 会自动将 Source 属性设置回其原始值。

        免责声明:我现在无法对此进行测试,因此请谨慎对待,可能还要进行一些调试工作......

        【讨论】:

        • 我必须承认——我对 XAML 几乎一无所知。如何定义“myCondition”组件?或者,如何从程序端更改要尝试的值?
        • 不幸的是,由于“触发器集合成员必须是 EventTrigger 类型。”
        • 数据触发器应放置在图像的样式触发器内。正如@BSchlinker 在上述评论中指出的那样,您的代码将引发异常。检查此stackoverflow.com/questions/2414358/…
        • 这实际上是我反复遇到的陷阱之一 ;-)
        【解决方案5】:

        如果你的图像定义是这样的:

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

        然后在您想要进行切换的代码中只需:

        ImageSource = image;
        

        其中image 定义为:

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

        当然,它确实依赖于您使用 MVVM 模式并在您的代码中实现 INotifyPropertyChanged 接口。

        【讨论】:

          猜你喜欢
          • 2015-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-14
          • 1970-01-01
          • 2011-08-03
          • 2021-03-24
          • 1970-01-01
          相关资源
          最近更新 更多