I want to create a button in a WPF window that, when clicked, waits for the user to click on the window and acquires the location of the click. Once the location is acquired, the program will continue to the next line of code and display the location of the click.
<Window x:Class="WpfApp1.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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="Pick Point & Display it!" HorizontalAlignment="Left" Margin="301,172,0,0" VerticalAlignment="Top" Width="168" Click="Button_Click" RenderTransformOrigin="1.479,2.177"/>
</Grid>
</Window>
private void Button_Click(object sender, RoutedEventArgs e)
{
var point = WaitTillUserClicks();
MessageBox.Show(point.ToString());
}
private Point WaitTillUserClicks()
{
// Prompt the user for a mouse click and do not proceed unless he has clicked at least once on the Window
}
Here a solution with TaskCompletionSource
private TaskCompletionSource<Point> _clickSomeWhere;
private async void Button_Click( object sender, RoutedEventArgs e )
{
( sender as UIElement ).IsHitTestVisible = false;
try
{
var point = await ReadPointAsync();
MessageBox.Show( point.ToString() );
}
finally
{
( sender as UIElement ).IsHitTestVisible = true;
}
}
private async Task<Point> ReadPointAsync()
{
_clickSomeWhere = new TaskCompletionSource<Point>();
// here is your prompt
this.Title = "Please click on the point you like!";
try
{
return await _clickSomeWhere.Task;
}
finally
{
this.Title = "Thank you!";
}
}
private void Window_MouseDown( object sender, System.Windows.Input.MouseButtonEventArgs e )
{
if ( _clickSomeWhere != null )
{
_clickSomeWhere.TrySetResult( e.GetPosition( this ) );
_clickSomeWhere = null;
}
}