RelayCommand 未调用 Execute 方法 WPF
RelayCommand is not called Execute method WPF
我正在尝试在 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;
}
与上述评论相关。我已经检查了您提供的 RelayCommand
class,它看起来是正确的,但我有一个类似的,但看起来有些不同。应该是 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);
}
无论如何,您不需要在 ContolTemplate 中使用 Button
。我这样做:
<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
包含绝对 HTTPS url.
我正在尝试在 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;
}
与上述评论相关。我已经检查了您提供的 RelayCommand
class,它看起来是正确的,但我有一个类似的,但看起来有些不同。应该是 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);
}
无论如何,您不需要在 ContolTemplate 中使用 Button
。我这样做:
<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
包含绝对 HTTPS url.