如何检查鼠标是否在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#初学者。所以如果你能发布一个最低工作范例,我会非常感激。
以下是您的示例应用程序。
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秒? – jams
它不需要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>
它不会做你说它应该做的事情。当我将鼠标悬停在按钮上数秒钟时,就没有输出。 –
您是否在dt_Tick方法中添加了代码?您必须在您的XAML或我的代码中更改MouseEnter和MouseLeave事件的方法名称。看我的编辑。 –
是的。我添加了一个简单的'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
我不明白正是你所需要的逻辑,但我认为这两个类,您可以在事件做你想做的事。
逻辑是,我将使用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);
}
}
您可以检查我的更新答案。 – jams
你究竟试过了什么?我没有看到任何企图,只是毫无价值的评论,这并不难。正如'jam'指出你想要使用的事件是'MouseEnter'这仍然是一个重复http://stackoverflow.com/questions/12638179/time-delay-on-trigger –
@Rhhound问题是,我没有知道该怎么尝试。我正在尝试一些人在答案中提出的建议,但他们似乎没有为我工作。 –