简体   繁体   English

如何从Click事件WPF停止Button Command执行

[英]How to stop the Button Command execution from its Click event WPF

Is there any way to stop the Button command execution based on some condition on its click event? 有没有办法根据Click事件的某些条件停止Button命令的执行?

Actually I want to have confirmation popup on some of the button click in our application. 实际上我想在我们的应用程序中点击一些按钮确认弹出窗口。 To make it a general solution, I have done the following: 为了使其成为一般解决方案,我做了以下工作:

  1. I have extension of WPF button class call AppBarButton which already contains some dependency properties. 我有WPF按钮类调用AppBarButton扩展,它已经包含一些依赖属性。
  2. I have 2 more properties for this as below: IsActionConfirmationRequired and ConfirmationActionCommand . 我还有2个属性,如下所示: IsActionConfirmationRequiredConfirmationActionCommand

If IsActionConfirmationRequired then on left button cick event I am opening the confirmation popup. 如果IsActionConfirmationRequired然后在左按钮cick事件我打开确认弹出窗口。

Is there any way to avoid creating new ConfirmationActionCommand , and use the same Command property of the Button ? 有没有办法避免创建新的ConfirmationActionCommand ,并使用Button的相同Command属性? The problem I am getting if I set Command , then on Button click even if user not confirmed the action still button command execute. 如果我设置Command ,我会得到的问题,然后Button即使用户没有确认动作仍然按钮命令执行。

C#: 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: XAML:

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

Please suggest something. 请提出建议。 I am not able to find anything. 我找不到任何东西。 Already tried CanExecute to false, but its make button disable so no use. 已经尝试过CanExecute为false,但是make按钮禁用所以没用。 I just simple dont want make another command, and developer who will use this AppBarButton need to set ConfirmationActionCommand not normal Command . 我只是简单的不想要另一个命令,并且将使用此AppBarButton开发人员需要设置ConfirmationActionCommand而不是正常的Command

If I correctly understand, you want to confirm user's action and execute a command which is stored in the ButtonBase.Command property. 如果我正确理解,您需要确认用户的操作并执行存储在ButtonBase.Command属性中的命令。

To achieve that remove the ConfirmationActionCommand property and use the OnClick method instead of the Click event. 要实现这一点,请删除ConfirmationActionCommand属性并使用OnClick方法而不是Click事件。 In the overriden OnClick method call the base method which will execute a command from the Command property if an user confirmed an action or there is no confirmation required. 在重写的OnClick方法中,调用base方法,如果用户确认操作或者不需要确认,它将从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();
        }
    }
}

Instead of the click event, handle the PreviewMouseLeftButtonDown event. 而不是click事件,处理PreviewMouseLeftButtonDown事件。 This occurs before the command executes. 这在命令执行之前发生。 In the handler ask for confirmation and set the Handled property of the event to true or false. 在处理程序中请求确认并将eventHandled属性设置为true或false。
If you set it to true, the command will not be executed. 如果将其设置为true,则不会执行该命令。

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

Here is how your code could look like (I dont know exactly because I dont have the code for ConfirmationDailog : 以下是您的代码的样子(我完全不知道,因为我没有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;
    }
    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM