分配给按钮的WPF更改方法暂时点击

时间:2016-06-12 05:50:31

标签: c# wpf multithreading xaml

我正在尝试在短时间内更改分配给按钮的按钮onclick处理程序/方法。

换句话说......用户点击按钮 - >按钮执行的主要任务 - >如果用户再次点击按钮...说3秒 - >按钮的次要任务执行。

如果用户未在3秒内单击该按钮,则主要任务将恢复为该按钮。

我已成功更改和恢复按钮功能......但是辅助方法没有完全执行。

这是xaml和cs代码......我在cs代码中添加了注释,因此很容易弄清楚我正在尝试做什么,以及我遇到问题的地方。

MainWindow.xaml:

<Window x:Class="UITest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:UITest"
        mc:Ignorable="d"
        Title="MainWindow" Height="519" Width="656">
    <StackPanel>
        <Button x:Name="button1" Width="60" Height="30" Content="button" Margin="10 10 0 0" BorderThickness="0" BorderBrush="{x:Null}" Padding="0" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Bisque" FontSize="16">
            <Button.Style>
                <Style TargetType="Button">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="Button">
                                <StackPanel Background="{TemplateBinding Background}">
                                    <ContentPresenter />
                                </StackPanel>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Button.Style>
        </Button>

        <Label x:Name="label1" Width="200" Height="30" Margin="10 10 0 0" BorderThickness="0" BorderBrush="{x:Null}" Padding="0" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="20" Content="label">
        </Label>
    </StackPanel>
</Window>

MainWindow.xaml.cs

namespace UITest
{
    public partial class MainWindow : Window
    {
        bool isClick2Done = true;
        public MainWindow()
        {
            InitializeComponent();
            this.button1.Click += Button1_Click1;
        }

        //primary function of button
        private async void Button1_Click1(object sender, RoutedEventArgs e)
        {
            label1.Content = "primary";

            //wait for a second, to avoid human error of double click
            await Task.Delay(1000);

            changeButtonFunction();
        }

        //secondary function of button
        private async void Button1_Click2(object sender, RoutedEventArgs e)
        {
            isClick2Done = false;   //click2 isn't done yet
            label1.Content = "secondary";

            //delay function
            //to observe whether this secondary method gets completed or not
            await Task.Delay(3000);
            label1.Content = "secondary after wait";
            await Task.Delay(2000);
            isClick2Done = true;   //click2 is now done
            restoreButtonFunction();
        }

        private async void changeButtonFunction()
        {
            //set new function for button
            this.button1.Click -= Button1_Click1;
            this.button1.Click += Button1_Click2;

            //button is now green - indicator that button has new function
            button1.Background = Brushes.Green;

            //keep new function for specific seconds
            //is there a better way of doing this?
            await Task.Delay(3000);

            //restore original button function
            while(!isClick2Done) { }
            restoreButtonFunction();
        }

        private async void restoreButtonFunction()
        {
            button1.Background = Brushes.Bisque;
            label1.Content = "label";
            this.button1.Click -= Button1_Click2;
            this.button1.Click += Button1_Click1;
        }
    }
}

编辑:我认为问题是 - 在Button1_Click2()之前,restoreButtonFuntion()已经完成......但我不确定。

1 个答案:

答案 0 :(得分:2)

使用计时器和一个公共事件处理程序。

当用户第一次点击时,启动计时器。设置定时器间隔为3000毫秒。因此,当处理计时器滴答时,恢复主要功能。在第一次按下按钮期间执行主要功能并启动计时器。

您还可以使用标志来标识同一处理程序中的第二次单击。当计时器滴答处理为3000毫秒时重置标志。

通过正确设置canExecute,使用中继命令和交互性也可以实现这一点。