RelayCommand CanExecute行为不起作用

时间:2010-09-20 20:16:24

标签: c# wpf mvvm-light

我无法让RelayCommand正确启用/禁用连接的控件。

我有一个EventToCommand元素附加到按钮上。该命令被数据绑定到ViewModel。最初,按钮被禁用(预期的行为),但我似乎无法获得CanExecute逻辑来检查它的值。设置并存在CurrentConfigFile时,应启用该按钮。我已经执行了代码并在调试中检查了文件的值以确保它已设置,但控件仍然被禁用。我已尝试CommandManager.InvalidateRequerySuggested()command.RaiseCanExecuteChanged(),但无法启用。

我想知道lambdas是否对CanExecute行为不起作用(即使示例使用它们),或者CanExecute行为需要数据绑定到另一个元素。

这是我的代码:

// The FileInfo being checked for existence before the button should be enabled
public const string CurrentConfigFilePN = "CurrentConfigFile";
public FileInfo CurrentConfigFile
{
    get
    {
        return _currentConfigFile;
    }

    set
    {
        if (_currentConfigFile == value)
        {
            return;
        }

        var oldValue = _currentConfigFile;
        _currentConfigFile = value;

        // Update bindings, no broadcast
        RaisePropertyChanged(CurrentConfigFilePN);
    }
}

public MainViewModel()
{
    // snip //

    SaveCommand = new RelayCommand(SaveConfiguration, 
        () => CurrentConfigFile != null && CurrentConfigFile.Exists);
    }

private void SaveConfiguration()
{

    // export model information to xml document
    ExportXMLConfiguration(CurrentConfigFile);

}

和标记

<Button x:Name="SaveButton" Content="Save" Width="75" Margin="20,5">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <GalaSoft:EventToCommand x:Name="SaveETC" 
                Command="{Binding SaveCommand}" 
                MustToggleIsEnabledValue="true" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

更新

根据Isak Savo的建议,我将RelayCommand直接绑定到按钮

<Button x:Name="SaveButton" Content="Save" Width="75" Margin="20,5" 
Command="{Binding SaveCommand}"/>

并在设置FileInfo时启动已禁用且已正确启用。猜猜我应该记住不要修复没有破坏的东西!

2 个答案:

答案 0 :(得分:2)

为什么不直接从Button绑定到Command?

<Button Command="{Binding SaveCommand}" Content="Save" />

您使用的EventToCommand可能正在使用命令的CanExecute通知搞乱。

关于CanExecute问题 - 您确定在设置CurrentConfigFile属性后调用CanExecute处理程序吗?我发现即使WPF在重新查询CanExecute方面做得很好,我仍然有时需要通过CommandManager强制重新查询。

编辑:正如评论中所指出的,OP已经尝试过命令管理器方法。

答案 1 :(得分:1)

msdn写道:

首次调用时,FileInfo调用Refresh并缓存有关该文件的信息。在后续调用中,您必须调用Refresh以获取信息的最新副本。

但是,我不会在CanExecute-handler中进行这样的检查。这可能会降低您的UI速度,因为CanExecute被调用了很多次,我可以想象这样的IO检查会变慢,例如,如果文件位于网络共享上。