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

WPF按钮根据命令执行结果实现样式切换与动画效果

WPF ListView保存按钮样式切换与命令逻辑分离方案

一、抽离保存命令逻辑

创建独立的SaveCommand类实现ICommand,将保存逻辑完全从ItemViewModel中剥离,仅依赖ISettingsManager、配置数据和结果回调:

public class SaveCommand : ICommand
{
    public enum SaveResult
    {
        None,
        Success,
        Failure
    }

    private readonly ISettingsManager _settingsManager;
    private readonly object _configData;
    private readonly Action<SaveResult> _onSaveCompleted;

    public SaveCommand(ISettingsManager settingsManager, object configData, Action<SaveResult> onSaveCompleted)
    {
        _settingsManager = settingsManager;
        _configData = configData;
        _onSaveCompleted = onSaveCompleted;
    }

    public bool CanExecute(object parameter) => true;

    // 若ISettingsManager.Save为同步方法,移除async/await即可
    public async void Execute(object parameter)
    {
        try
        {
            await _settingsManager.Save(_configData);
            _onSaveCompleted?.Invoke(SaveResult.Success);
        }
        catch (Exception)
        {
            _onSaveCompleted?.Invoke(SaveResult.Failure);
        }
    }

    public event EventHandler CanExecuteChanged;
}

二、调整ItemViewModel职责

ItemViewModel仅维护保存结果状态,不包含命令逻辑,通过构造函数注入依赖并创建命令:

public class ItemViewModel : INotifyPropertyChanged
{
    private SaveCommand.SaveResult _saveResult = SaveCommand.SaveResult.None;
    public SaveCommand.SaveResult SaveResult
    {
        get => _saveResult;
        set
        {
            _saveResult = value;
            OnPropertyChanged();
        }
    }

    public ICommand SaveCommand { get; }

    public ItemViewModel(ISettingsManager settingsManager, YourConfigType configData)
    {
        SaveCommand = new SaveCommand(settingsManager, configData, result =>
        {
            SaveResult = result;
            // 可选:2秒后重置状态,按钮自动恢复默认样式
            Task.Delay(2000).ContinueWith(_ => SaveResult = SaveCommand.SaveResult.None);
        });
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

三、ItemView中绑定样式与命令

在列表项的XAML中,通过DataTrigger根据SaveResult切换按钮样式,并添加动画效果:

<Button Content="保存"
        Command="{Binding SaveCommand}">
    <Button.Style>
        <Style TargetType="Button">
            <!-- 默认样式 -->
            <Setter Property="Background" Value="#FF0078D7"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Padding" Value="8,4"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Style.Triggers>
                <!-- 成功状态样式与动画 -->
                <DataTrigger Binding="{Binding SaveResult}" Value="Success">
                    <Setter Property="Background" Value="#FF00B248"/>
                    <DataTrigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="Opacity"
                                                 From="0.6" To="1" Duration="0:0:0.3"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                </DataTrigger>
                <!-- 失败状态样式与动画 -->
                <DataTrigger Binding="{Binding SaveResult}" Value="Failure">
                    <Setter Property="Background" Value="#FFE81123"/>
                    <DataTrigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="Opacity"
                                                 From="0.6" To="1" Duration="0:0:0.3"/>
                                <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX"
                                                 From="0.9" To="1.1" RepeatBehavior="3x" AutoReverse="True" Duration="0:0:0.1"/>
                                <DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY"
                                                 From="0.9" To="1.1" RepeatBehavior="3x" AutoReverse="True" Duration="0:0:0.1"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
    <Button.RenderTransform>
        <ScaleTransform/>
    </Button.RenderTransform>
</Button>

四、核心说明

  • 命令逻辑完全独立,ItemViewModel仅承担状态维护职责,符合单一原则。
  • 通过SaveResult枚举作为绑定源,实现样式与业务逻辑的解耦。
  • 可根据需求调整动画效果或状态重置延迟时间,优化用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 21:53:11