【问题标题】:How to check if mouse is over a button in wpf如何检查鼠标是否在wpf中的按钮上
【发布时间】:2012-10-16 10:52:27
【问题描述】:

在我开始之前,我必须说一下。我读过this question。而且我看不到它与我几个小时前发布的this question 的重复。

我原来的帖子是这样的:

我在 WPF 中使用了一些按钮来显示来自不同文件夹的图像。所有按钮的Click 模式为Hover。对于某些按钮,悬停后,它被路由到函数OnButtonClick。我想要做的是,只有在鼠标悬停在按钮上X 秒后,才能完成函数OnButtonClick 内部的处理。

XAML 代码:

    <Button Name="Dresses" MouseEnter="onMouseEnter" MouseLeave="onMouseLeave" Content="Dresses" Grid.Row="2" Height="25" Width="85" VerticalAlignment="Center" Grid.Column="5"  FontFamily="Tahoma" FontSize="14" FontWeight="Bold" HorizontalAlignment="Center" Cursor="Hand" ClickMode="Hover">
        <Button.Background>
            <LinearGradientBrush>
                <GradientStop Color="Yellow" Offset="0" />
                <GradientStop Color="Green" Offset="1" />
            </LinearGradientBrush>
        </Button.Background>
    </Button>

C#代码:

    private void OnButtonClickDresses(object sender, RoutedEventArgs e)
    {
            //Code for delay

            //Code which should run only if mouse on button after 5 seconds

    }

PS:我是 WPF 和 C# 的初学者。因此,如果您能发布一个最低限度的工作示例,我将非常感激。

【问题讨论】:

  • 你可以查看我更新的答案。
  • 您到底尝试了什么?我没有看到任何尝试,只是毫无价值的 cmets,这并不难。正如jams 指出您要使用的事件是MouseEnter 这仍然是stackoverflow.com/questions/12638179/time-delay-on-trigger 的副本
  • @Ramhound 问题是,我不知道该尝试什么。我正在尝试一些人在答案中提出的建议,但它们似乎对我不起作用。

标签: c# wpf click delay mouseover


【解决方案1】:

这是一个示例应用程序。

using System.Windows.Threading;

namespace MyWPF App
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>

public partial class MainWindow : Window
{

    DateTime dt;
    DispatcherTimer t;

    public MainWindow()
    {

        InitializeComponent();
        t = new DispatcherTimer();
        t.Tick += new EventHandler(t_Tick);

    }
    private void button1_MouseEnter(object sender, MouseEventArgs e)
    {
        dt=DateTime.Now;
        t.Interval = new TimeSpan(0, 0, 1);
        t.IsEnabled = true;


    }

    void t_Tick(object sender, EventArgs e)
    {

        if ((DateTime.Now - dt).Seconds >= 5)
        {
            MessageBox.Show("Hello");// Here you can put your code which you want to execute after 5 seconds.
        }

    }

    private void button1_MouseLeave(object sender, MouseEventArgs e)
    {
        t.IsEnabled = false;
    }
}

}

【讨论】:

  • 您能否根据我引用的代码详细说明我如何做到这一点?
  • 为什么要等待 5 秒?
  • 不需要5秒。可以说是X 秒。我想要做的是,如果鼠标在按钮上停留的时间超过X 秒,那么只有这样分配给该按钮的特定进程才会发生。
  • @Karan Thakkar:请告诉我它对你有用吗?
  • 它没有做你说它应该做的事情。当我将鼠标悬停在按钮上任意秒数时,没有输出。
【解决方案2】:

您可以使用 MouseEnter 启动一个间隔为 X 秒的 Timer。在 MouseLeave 上,您停止此计时器。现在您将 OnButtonClickDresses 方法中的代码放入 Timer_Tick 方法中。

示例:

public partial class MainWindow : Window
{
    DispatcherTimer dt;

    public MainWindow()
    {
        InitializeComponent();
        dt = new DispatcherTimer();
        dt.Interval = new TimeSpan(0, 0, 5);//wait for 5 Seconds
        dt.Tick += new EventHandler(dt_Tick);
    }

    void dt_Tick(object sender, EventArgs e)
    {
        //do code
    }

    private void button1_MouseEnter(object sender, MouseEventArgs e)
    {
        dt.Start();
    }

    private void button1_MouseLeave(object sender, MouseEventArgs e)
    {
        dt.Stop();
    }
}

编辑:

    <Button Name="Dresses" MouseEnter="button1_MouseEnter" MouseLeave="button1_MouseLeave" Content="Dresses" Grid.Row="2" Height="25" Width="85" VerticalAlignment="Center" Grid.Column="5"  FontFamily="Tahoma" FontSize="14" FontWeight="Bold" HorizontalAlignment="Center" Cursor="Hand"
        <Button.Background>
            <LinearGradientBrush>
                <GradientStop Color="Yellow" Offset="0" />
                <GradientStop Color="Green" Offset="1" />
            </LinearGradientBrush>
        </Button.Background>
    </Button>

【讨论】:

  • 它没有做你说它应该做的事情。当我将鼠标悬停在按钮上任意秒数时,没有输出。
  • 您是否在 dt_Tick - 方法中添加了代码?您必须在 XAML 或我的代码中更改 MouseEnter 和 MouseLeave 事件的方法名称。查看我的编辑。
  • 是的。我添加了一个简单的MessageBox 只是为了检查它是否进入了那个循环。但不,不是。
  • 之后就可以了。但是@jams 在我阅读您的评论之前在聊天中告诉我。所以我将他的答案标记为正确。但是您的答案也可以正常工作。谢谢。
【解决方案3】:

不能在方法中使用:

System.Threading.Thread.Sleep (5000);

因为这会冻结你的界面。

为此,您应该使用某种异步任务。 我推荐:

Task.Factory.StartNew (() =>
{
   System.Threading.Thread.Sleep (5000);
})
. ContinueWith (() =>
{
     / / Code after 5 seconds
}
TaskScheduler.FromCurrentSynchronizationContext ());

虽然我不认为它是理想的,因为它可以将鼠标移到上面,然后放回去。这可能会导致混淆。

我推荐的方法:

使用事件 MouseEnter 和 MouseLeave 以及类

System.Diagnostics.Stopwatch 
System.Windows.Threading.DispatcherTimer

我不完全理解你需要的逻辑,但我认为通过这两个类和事件你可以做你想做的事。

【讨论】:

  • 逻辑是,我将使用我的手部动作控制鼠标,使用 Kinect。因此,为了避免意外悬停在某个按钮上,我添加了延迟。因此,如果鼠标在某个按钮上停留几秒钟,则该按钮将被激活。
【解决方案4】:

这似乎适用于任意数量的按钮...

XAML:

    <Grid>
        <Button Name="myButton1" Content="Button 1" HorizontalAlignment="Left" Margin="34,51,0,0" VerticalAlignment="Top" Width="75" Click="HoverButton_Click" MouseEnter="HoverButton_MouseEnter" MouseLeave="HoverButton_MouseLeave"/>
        <Button Name="myButton2" Content="Button 2" HorizontalAlignment="Left" Margin="150,51,0,0" VerticalAlignment="Top" Width="75" Click="HoverButton_Click" MouseEnter="HoverButton_MouseEnter" MouseLeave="HoverButton_MouseLeave"/>
        <TextBox Name="myTextBox" HorizontalAlignment="Left" Height="147" Margin="34,91,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="232"/>
    </Grid>

代码:

    private Dictionary<Button, System.Threading.Timer> buttonTimers = new Dictionary<Button, System.Threading.Timer>();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void HoverTime(object state)
    {
        var thisButton = state as Button;

        thisButton.Dispatcher.BeginInvoke((Action)delegate()
        {
            thisButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
        });
    }

    private void HoverButton_Click(object sender, RoutedEventArgs e)
    {
        var button = sender as Button;

        myTextBox.Text += "Delayed hover: " + button.Content + Environment.NewLine;
    }

    private void HoverButton_MouseEnter(object sender, MouseEventArgs e)
    {
        var thisButton = sender as Button;

        var t = new System.Threading.Timer(new TimerCallback(HoverTime), sender, 2500, Timeout.Infinite);

        buttonTimers.Add(thisButton, t);
    }

    private void HoverButton_MouseLeave(object sender, MouseEventArgs e)
    {
        var thisButton = sender as Button;

        if (buttonTimers.ContainsKey(thisButton))
        {
            buttonTimers[thisButton].Dispose();
            buttonTimers.Remove(thisButton);
        }
    }

【讨论】:

    猜你喜欢
    • 2012-10-06
    • 2019-05-05
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多