简体   繁体   English

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

[英]How to check if mouse is over a button in wpf

Before I start, I have to say this. 在我开始之前,我必须说这个。 I have read this question . 我已经读过这个问题 And I dont see how its a duplicate of this question that I posted a few hours ago. 而且我看不到它是几个小时前发布的这个问题的副本。

My original post as it is: 我的原始帖子是:

I am using a few buttons in WPF for displaying images from various folders. 我在WPF中使用了一些按钮来显示来自各个文件夹的图像。 The Click mode for all the buttons is Hover . 所有按钮的“ Click模式为“ Hover For some button, after hovering, it is routed to a function OnButtonClick . 对于某些按钮,将OnButtonClick悬停后将其路由到函数OnButtonClick What I want to do is, ONLY after the mouse is over the button for X seconds, the processing inside the function OnButtonClick should be done. 我想做的是,只有在鼠标悬停在按钮上X秒钟之后,才应该完成函数OnButtonClick内的处理。

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

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

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

    }

PS: I am a beginner in WPF and C#. PS:我是WPF和C#的初学者。 So if you can post a minimum working example I'd be actually very grateful. 因此,如果您能发布一个最低限度的工作示例,我将非常感激。

Here is a sample application for you. 这是给您的示例应用程序。

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

}

You can use MouseEnter to start a Timer which has an interval of X seconds. 您可以使用MouseEnter启动间隔为X秒的计时器。 On MouseLeave you stop this Timer. 在MouseLeave上,您可以停止此计时器。 Now you put the code from the OnButtonClickDresses-method in the Timer_Tick method. 现在,您将来自OnButtonClickDresses方法的代码放入Timer_Tick方法中。

Sample: 样品:

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

EDIT: 编辑:

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

You can not use it in the method: 您不能在方法中使用它:

System.Threading.Thread.Sleep (5000);

For the reason that will freeze your interface. 因为这样会冻结您的界面。

For that you should use some sort of asynchronous task. 为此,您应该使用某种异步任务。 I recommend: 我建议:

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

Although I do not think it is ideal because it can remove the mouse over, and put back. 尽管我认为这不是理想的选择,因为它可以将鼠标移至上方并放回原处。 This can cause confusion. 这会引起混乱。

My recommended approach: 我推荐的方法:

Use the events MouseEnter and MouseLeave, and classes 使用事件MouseEnter和MouseLeave以及类

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

I do not understand exactly the logic you need, but I think with these two classes and the events you can do what you want. 我不完全了解您需要的逻辑,但是我认为通过这两个类和事件,您可以执行所需的操作。

This seems to work OK for an arbitrary number of buttons... 对于任意数量的按钮,这似乎都可以正常工作...

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

Code: 码:

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

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

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