简体   繁体   中英

How to trigger an event only when the user ctrl click the lower half of a button?

I want to implement some secret features in my application and they can only be invoked by ctrl left click the lower half of a button. Is this possible to implement in WPF? I tried to create a demo app and debugging doesn't show me the cursor position information in the click event handler. Below is my test code. Any ideas?

<Window x:Class="WpfApplication1.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:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="255.284" Width="313.918">
    <Grid>
        <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="81,89,0,0" VerticalAlignment="Top" Width="158" Height="49" Click="button_Click"/>
    </Grid>
</Window>
using System.Windows;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e)
        { // <----- set break point here, can't find cursor info in e and sender

        }
    }
}

You can use the MouseUp or MouseDown events, which both give you the mouse position in the event arguments, as well as which mouse button was pressed.

Mouse up is triggered when the mouse button is lifted while inside the button, while mouse down (can you guess?) when it's pressed down while inside the button.

EDIT : I just checked the details for MouseDown and you'll have to use

Point p = e.GetPosition(yourButton);

to get the position of the mouse relative to the button (you can replace yourButton by any control to get the mouse position relative to it)

There are so many ways to do this!

In addition to the answers provided, which I think are correct, you can also play around with the layout. For example, you can define a border, containing two buttons where the user will think that there's only one button:

<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Width="250" Height="100" >
    <Border BorderBrush="Black" BorderThickness="1" MouseEnter="border_MouseEnter" MouseLeave="border_MouseLeave">
        <StackPanel>
            <Button  VerticalAlignment="Top" Height="50" Style="{StaticResource ButtonStyle}" Content="MainButton"></Button>
            <Button  VerticalAlignment="Bottom" Content="SecretArea" Style="{StaticResource ButtonStyle}" Height="50" Click="Button_Click"></Button>
        </StackPanel>
    </Border>
</Grid>

By removing borders from the buttons in a style that you defined, you would have something like this:

在此处输入图片说明

You can also set the background color of the border when the user hovers its mouse on it, using MouseEnter and MouseLeave events.

Anyway, when the user clicks the secret area button, you can simply handle the event:

private void Button_Click(object sender, RoutedEventArgs e)
{
      MessageBox.Show("Secret Area");
}

You can use Mouse.GetPosition to get the cursor position relative to the corner of the button and compare the position to the ActualHeight of the button:

var pos = Mouse.GetPosition(button);
if(pos.Y >= button.ActualHeight * 0.5)
{
    //do something
}

Add a second button on top of the lower half of your existing button, but set it to be invisible to the user.

You can then program its click handler to do exactly what you want, and even activate the click handler of the underlying, visible button if you so desire.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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