You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过继承Button与XAML样式实现随IsExecuting切换图片的自定义按钮

解决方法

1. 先确认ViewModelBase的INotifyPropertyChanged实现

你的AsyncCommand继承了ViewModelBase,得确保这个基类已经正确实现了INotifyPropertyChanged接口——不然IsExecuting的属性变更没法通知到UI,后续的绑定都白搭。

2. 自定义Button类(极简版)

不用加任何额外属性,直接继承Button就行,主要是给样式一个明确的目标类型:

public class CustomButton : Button
{
    // 啥都不用写,就当个空壳子
}

3. 核心:写XAML样式实现图片切换

用DataTrigger直接绑定按钮的Command.IsExecuting属性,根据状态切换显示的图片。假设你已经在资源里定义了NormalImage(正常状态图)和LoadingImage(执行中图):

<Style TargetType="{x:Type local:CustomButton}">
    <!-- 默认显示正常状态图片 -->
    <Setter Property="Content">
        <Setter.Value>
            <Image Source="{StaticResource NormalImage}" />
        </Setter.Value>
    </Setter>
    <!-- 当IsExecuting为True时切换到加载图 -->
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Command.IsExecuting}" Value="True">
            <Setter Property="Content">
                <Setter.Value>
                    <Image Source="{StaticResource LoadingImage}" />
                </Setter.Value>
            </Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>

为啥之前用CanExecuteChanged没成功?

CanExecuteChanged是用来通知命令是否可执行的,虽然你的AsyncCommand在IsExecuting变化时会触发这个事件,但它本质上是让UI更新按钮的可点击状态,不是直接关联IsExecuting的值。直接绑定Command.IsExecuting才是最直接准确的方式,毕竟这个属性就是专门用来标识命令是否在执行的。

4. 进阶:带复杂布局的按钮

如果按钮不止显示图片,还要加文字啥的,可以用ContentTemplate结合内部触发器来控制元素可见性:

<Style TargetType="{x:Type local:CustomButton}">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Image x:Name="NormalImg" Source="{StaticResource NormalImage}" />
                    <Image x:Name="LoadingImg" Source="{StaticResource LoadingImage}" Visibility="Collapsed" />
                    <TextBlock Text="操作" Margin="5,0,0,0" />
                </StackPanel>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:CustomButton}}, Path=Command.IsExecuting}" Value="True">
                        <Setter TargetName="NormalImg" Property="Visibility" Value="Collapsed" />
                        <Setter TargetName="LoadingImg" Property="Visibility" Value="Visible" />
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

5. 最终使用

在XAML里直接用自定义按钮,绑定你的AsyncCommand就行:

<local:CustomButton Command="{Binding YourAsyncCommandInstance}" />

内容的提问来源于stack exchange,提问作者Taras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:22:39