如何从其单击事件WPF停止按钮命令的执行

本文关键字:按钮 命令 执行 WPF 单击 事件 | 更新日期: 2023-09-27 18:18:46

是否有任何方法可以根据其单击事件的某些条件停止按钮命令执行?

实际上,我希望在我们的应用程序中的某些按钮点击时弹出确认。为了使它成为一个通用的解决方案,我做了以下工作:

    我已经扩展了WPF按钮类调用AppBarButton,它已经包含一些依赖属性。
  1. 我有两个以上的属性如下:IsActionConfirmationRequiredConfirmationActionCommand

如果IsActionConfirmationRequired然后在左键点击事件,我打开确认弹出。

是否有任何方法可以避免创建新的ConfirmationActionCommand,并使用Button相同的Command属性?如果我设置Command,那么在Button上单击,即使用户没有确认动作仍然按钮命令执行。

c#:

public class AppBarButton : Button
{
    public AppBarButton()
    {
        this.Click += AppBarButton_Click;
    }
    private void AppBarButton_Click(object sender, RoutedEventArgs e)
    {
        Button button = sender as Button;
        if (button == null || IsActionConfirmationRequired == false || ConfirmationActionCommand == null)
            return;
        const string defaultMessage = "Do you really want to {0}";
        string confirmationPopUpMessage = string.IsNullOrEmpty(ActionConfirmationMessage)
          ? DebugFormat.Format(defaultMessage, button.Content)
          : ActionConfirmationMessage;
        ConfirmationDailogDetails confirmationDailogDetails = new ConfirmationDailogDetails
        {
            Message = confirmationPopUpMessage,
            ActionName = button.Content.ToString(),
            Template = button.Template,
            ActionCommand = ConfirmationActionCommand
        };
        //instead of ConfirmationActionCommand want to use base.Command
        ConfirmationDailog dialog = new ConfirmationDailog(confirmationDailogDetails)
        {
            PlacementTarget = button,
            IsOpen = true
        };
    }
    public static readonly DependencyProperty IsActionConfirmationRequiredProperty =
        DependencyProperty.Register("IsActionConfirmationRequired", typeof(bool), typeof(AppBarButton));
    public static readonly DependencyProperty ActionConfirmationMessageProperty =
        DependencyProperty.Register("ActionConfirmationMessage", typeof(string), typeof(AppBarButton));
    public static readonly DependencyProperty ConfirmationActionCommandProperty =
       DependencyProperty.Register("ConfirmationActionCommand", typeof(ICommand), typeof(AppBarButton));
    /// <summary>
    /// Gets or sets the flag to show the confirmation popup on before taking any action on App Bar button click.
    /// Also its required to set the command in Tag Property of the App Bar button not in the Command Property, then only required command will fire only when user
    /// confirms and click on the action button on confirmation popup.
    /// </summary>
    public bool IsActionConfirmationRequired
    {
        get { return (bool)GetValue(IsActionConfirmationRequiredProperty); }
        set { SetValue(IsActionConfirmationRequiredProperty, value); }
    }
    /// <summary>
    /// Gets or sets the confirmation message in confirmation popup  before taking any action on App Bar button click.
    /// </summary>
    public ICommand ConfirmationActionCommand
    {
        get { return (ICommand)GetValue(ConfirmationActionCommandProperty); }
        set { SetValue(ConfirmationActionCommandProperty, value); }
    }
}
XAML:

<controls:AppBarButton x:Key="WithdrawAll"
                       AppBarOrder="1"
                       PageIndex="1"
                       AppBarOrientation="Left"
                       Content="Withdraw" IsActionConfirmationRequired="True"
                       ConfirmationActionCommand="{Binding WithdrawAllCommand}"
                       Template="{StaticResource DeleteCircleIcon}" />

请提出建议。我什么也找不到。已经尝试了CanExecute为假,但它的使按钮禁用,所以没有使用。我只是简单地不想做另一个命令,开发人员将使用这个AppBarButton需要设置ConfirmationActionCommand而不是正常的Command

如何从其单击事件WPF停止按钮命令的执行

如果我理解正确的话,您想要确认用户的操作并执行存储在ButtonBase.Command属性中的命令。

要实现这一点,请删除ConfirmationActionCommand属性并使用OnClick方法而不是Click事件。在重写的OnClick方法中,调用基方法,如果用户确认操作或不需要确认,则基方法将执行来自Command属性的命令。

public class AppBarButton : Button
{
    public static readonly DependencyProperty IsActionConfirmationRequiredProperty =
        DependencyProperty.Register("IsActionConfirmationRequired", typeof(bool), typeof(AppBarButton));
    public static readonly DependencyProperty ActionConfirmationMessageProperty =
        DependencyProperty.Register("ActionConfirmationMessage", typeof(string), typeof(AppBarButton));
    public bool IsActionConfirmationRequired
    {
        get { return (bool)GetValue(IsActionConfirmationRequiredProperty); }
        set { SetValue(IsActionConfirmationRequiredProperty, value); }
    }
    public string ActionConfirmationMessage
    {
        get { return (string)GetValue(ActionConfirmationMessageProperty ); }
        set { SetValue(ActionConfirmationMessageProperty , value); }
    }
    protected override void OnClick()
    {
        bool confirmed = true;
        if (IsActionConfirmationRequired)
        {
            ConfirmationDailogDetails confirmationDailogDetails = new ConfirmationDailogDetails
            {
                Message = confirmationPopUpMessage,
                ActionName = button.Content.ToString(),
                Template = button.Template,
                ActionCommand = ConfirmationActionCommand
            };
            ConfirmationDailog dialog = new ConfirmationDailog(confirmationDailogDetails)
            {
                PlacementTarget = button,
                IsOpen = true
            };
            // Set confirmed here
            // If you set the DialogResult property in the ConfirmationDailog class then
            // confirmed = dialog.ShowDialog().Value;
        }
        // If there is no confirmation requred or if an user have confirmed an action
        // then call base method which will execute a command if it exists.
        if (confirmed)
        {
            base.OnClick();
        }
    }
}

处理PreviewMouseLeftButtonDown事件,而不是点击事件。这在命令执行之前发生。在处理程序中请求确认并将eventHandled属性设置为true或false。
如果设置为true,则不执行该命令。

private void btn_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    var confirmed = true;   //use your confirmation instead
    e.Handled = confirmed;
}

这是你的代码可能看起来像(我不知道确切的,因为我没有ConfirmationDailog的代码:

public class AppBarButton : Button
{
    public AppBarButton()
    {
        this.PreviewMouseLeftButtonDown += AppBarButton_PreviewMouseLeftButtonDown; ;
    }
    private void AppBarButton_PreviewMouseLeftButtonDown(object sender, RoutedEventArgs e)
    {
        Button button = sender as Button;
        if (button == null || IsActionConfirmationRequired == false || ConfirmationActionCommand == null)
            return;
        const string defaultMessage = "Do you really want to {0}";
        string confirmationPopUpMessage = string.IsNullOrEmpty(ActionConfirmationMessage)
          ? DebugFormat.Format(defaultMessage, button.Content)
          : ActionConfirmationMessage;
        ConfirmationDailogDetails confirmationDailogDetails = new ConfirmationDailogDetails
        {
            Message = confirmationPopUpMessage,
            ActionName = button.Content.ToString(),
            Template = button.Template,
            ActionCommand = ConfirmationActionCommand
        };
        **//instead of ConfirmationActionCommand want to use base.Command**
       ConfirmationDailog dialog = new ConfirmationDailog(confirmationDailogDetails)
       {
           PlacementTarget = button,
           IsOpen = true
       };
        //validation here
        dialog.ShowDialog();
        var confirmed = dialog.IsConfirmed;
        e.Handled = confirmed;
    }
    ...