如何检查鼠标是否在wpf中的按钮上

问题描述:

在我开始之前,我不得不说这个。我已阅读this question。我没有看到它是几个小时前发布的this question的副本。如何检查鼠标是否在wpf中的按钮上

我原来的职位,因为它是:

我使用的几个按键在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#初学者。所以如果你能发布一个最低工作范例,我会非常感激。

+0

您可以检查我的更新答案。 – jams

+0

你究竟试过了什么?我没有看到任何企图,只是毫无价值的评论,这并不难。正如'jam'指出你想要使用的事件是'MouseEnter'这仍然是一个重复http://*.com/questions/12638179/time-delay-on-trigger –

+1

@Rhhound问题是,我没有知道该怎么尝试。我正在尝试一些人在答案中提出的建议,但他们似乎没有为我工作。 –

以下是您的示例应用程序。

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; 
    } 
} 

} 
+0

你能否详细说明我如何根据我引用的代码来做到这一点? –

+0

为什么你想等5秒? – jams

+0

它不需要5秒。它可以说'X'秒。我想做什么,如果鼠标超过按钮超过'X'秒,那么只有当分配给该按钮的特定进程应该发生时才会发生。 –

您可以使用MouseEnter启动间隔为X秒的计时器。在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> 
+0

它不会做你说它应该做的事情。当我将鼠标悬停在按钮上数秒钟时,就没有输出。 –

+0

您是否在dt_Tick方法中添加了代码?您必须在您的XAML或我的代码中更改MouseEnter和MouseLeave事件的方法名称。看我的编辑。 –

+0

是的。我添加了一个简单的'MessageBox'来检查它是否进入该循环。但不,没有。 –

不能在该方法使用它:

System.Threading.Thread.Sleep (5000); 

对于将冻结您的接口的原因。

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

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

虽然我不认为这是理想的,因为它可以通过删除鼠标,并放回。这可能会导致混淆。

我推荐的方法:

使用事件的MouseEnter和鼠标离开,和类

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

我不明白正是你所需要的逻辑,但我认为这两个类,您可以在事件做你想做的事。

+0

逻辑是,我将使用Kinect控制鼠标的动作。所以为了避免意外地悬停在某个按钮上,我添加了延迟。所以如果鼠标在某个按钮上几秒钟,那么按钮将被激活。 –

这似乎工作确定任意数量的按钮...

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); 
     } 
    }