对于带有RelayCommand的Button,错误消息“无法为不可变对象实例上的'(0)。(1)'设置动画”

时间:2017-05-23 09:24:43

标签: c# wpf freezable

我使用由两个属性管理的扩展按钮:IsLockedIsRequiredIsLocked使用RelayCommand

停用该按钮
public class RelayCommand : ICommand
{
    private Action _execute;
    private Func<bool> _canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public RelayCommand(Action execute, Func<bool> canExecute = null)
    {
        this._execute = execute;
        this._canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return this._canExecute == null || this._canExecute();
    }

    public void Execute(object parameter)
    {
        this._execute();
    }
}

IsRequired用动画更改按钮的背景颜色。

这两个属性都是依赖的,并且定义如下:

public Boolean IsRequired
    {
        get { return _isRequired; }
        private set
        {
            if (_isRequired == value)
                return;

            _isRequired = value;

            if (_isRequired)
                this.IsLocked = false;

            NotifyPropertyChanged();
        }
    }

public Boolean IsLocked
    {
        get { return _isLocked; }
        private set
        {
            if (_isLocked == value)
                return;

            _isLocked = value;                

            if (_isLocked)
                this.IsRequired = false;

            NotifyPropertyChanged();
        }
    }

我通过viewmodel中的属性控制按钮,并在相关视图中对按钮属性进行绑定:

IsLocked="{Binding IsLocked}"
IsRequired="{Binding IsRequired}"

我在viewmodel中将IsRequired设置为True时,错误消息“无法在不可变对象实例上设置'(0)。(1)'。通常情况下,IsLocked为false(通过属性的Setter)但我看到属性IsEnabled仍为False。因此,我尝试更改IsEnabledPropertyChangedCallback链接到扩展按钮的依赖项属性。但这是不可能的,它被冻结了。

如果我不再使用CanExecute的{​​{1}}方法,并且我将扩展按钮的属性RelayCommand直接绑定到属性IsEnabled,那么该方法有效

有什么方法可以继续使用relay命令?

编辑: 这是我的扩展按钮的样式

IsLocked

标准按钮的样式在另一个名为Theme的项目中定义:

<Button x:Class="Client.UserControls.ExtendedButton"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:Client.UserControls"
         mc:Ignorable="d"
         d:DesignHeight="300" d:DesignWidth="300">
<Button.Style>
    <Style TargetType="{x:Type local:ExtendedButton}" BasedOn="{StaticResource {x:Type Button}}">
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsEnabled" Value="True"/>
                    <Condition Property="IsRequired" Value="True"/>
                </MultiTrigger.Conditions>
                <MultiTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard BeginTime="00:00:00"
                                RepeatBehavior="Forever"
                                Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)">
                            <ColorAnimation To="Orange" Duration="0:0:1" AutoReverse="True"/>
                        </Storyboard>
                    </BeginStoryboard>
                </MultiTrigger.EnterActions>
            </MultiTrigger>
        </Style.Triggers>
    </Style>
</Button.Style>

1 个答案:

答案 0 :(得分:0)

这可能是因为您没有使用情节提要(storyboard)为样式的初始背景笔刷设置值:

<Style TargetType="{x:Type local:ExtendedButton}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="{StaticResource DefaultBackgroundSolidColor}"/>
    <Style.Triggers>
        <MultiTrigger>
             ...