RelayCommand не вызывается методом Execute WPF - PullRequest
0 голосов
/ 29 марта 2020

Я пытаюсь использовать шаблон команды в WPF, полагаю, что после нажатия кнопки моя команда выполнит какое-то действие. Но он никогда не вызывал метод Execute. Я видел это в логах. Метод ShowPopUp () никогда не выполнялся, хотя метод CanShowPopUp () выполнялся несколько раз за одно нажатие кнопки.

<Window.Resources>
        <Style x:Key="CarButton" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
            <Setter Property="Width" Value="140"/>
            <Setter Property="Height" Value="Auto"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">

                        <Button Name="Chrome" Margin="0,10,0,10" ToolTipService.InitialShowDelay="10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                                HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" BorderThickness="1,1,1,1" BorderBrush="DarkGray" SnapsToDevicePixels="true" Padding="2">
                            <ContentPresenter ContentTemplate="{TemplateBinding Content}"/>
                            <ToolTipService.ToolTip>
                                <ToolTip>
                                    <TextBlock Text="{Binding ToolTip, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Width="Auto" Height="Auto"/>
                                </ToolTip>
                            </ToolTipService.ToolTip>
                        </Button>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="BorderBrush" Value="YellowGreen" />
                            </Trigger>

                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="BorderBrush" Value="OrangeRed" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

<Button  Margin="5,5,20,5" Grid.Row="0" Grid.Column="0" Style="{StaticResource CarButton}" Command="{Binding PopUpCommand}">
                            <Button.Resources>
                                <BitmapImage x:Key="ButtonImage" UriSource="/Image/peugeot.jpg"/>
                            </Button.Resources>
                            <Image Source="{StaticResource ButtonImage}" Stretch="Fill"/>
                        </Button>
// In code behind:
public partial class CarAgencyMainView : Window
    {
        CarAgencyMainViewModel carViewModel;
        public CarAgencyMainView()
        {
            InitializeComponent();
            carViewModel = new CarAgencyMainViewModel();
            this.DataContext = carViewModel; 
        }
    }
public class RelayCommand : ICommand
    {
        private readonly Action<object> action;
        private readonly Predicate<object> canExecute;
        public RelayCommand(Action<object> action) : this(action, null)
        { }
        public RelayCommand(Action<object> action,
        Predicate<object> canExecute )
        {
            this.action = action;
            this.canExecute = canExecute;
        }
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        public bool CanExecute(object parameter)
        {
            return canExecute == null ? true : canExecute(parameter);
        }
        public void Execute(object parameter)
        {
            this.action(parameter);
        }
    }

// in view model:

public ICommand PopUpCommand
        {
            get
            {
                return popUpCommand ?? (popUpCommand = new RelayCommand(param => ShowPopUp(), param => CanShowPopUp()));
            }
        }

        public void ShowPopUp()
        {
            IsOpen = true;
        }

        public bool CanShowPopUp()
        {
            return true;
        }

1 Ответ

0 голосов
/ 30 марта 2020

Связано с комментариями выше. Я проверил RelayCommand класс, который вы предоставили, и он выглядит правильно, но у меня есть похожий класс, который выглядит несколько иначе. Должно быть на 100% совместимо.

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);

    public void Execute(object parameter) => _execute(parameter);
}

В любом случае вам не нужен Button внутри ContolTemplate. Я делаю это так:

<Style x:Key="ImageButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <ContentPresenter/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

И Button

<Button Style="{StaticResource ImageButtonStyle}" Command="{Binding CmdOpenImageLink}">
    <Button.Content>
        <Image Source="{Binding ButtonImage}"/>
    </Button.Content>
</Button>

Здесь ButtonImage - это просто string, содержащий абсолютный URL-адрес HTTPS.

...