等到用户单击 C# WPF
Wait till user click C# WPF
我希望当用户点击 Button
时,程序等待用户点击 Window
并且不会继续执行下一行代码,除非 Point
通过单击 Window
获取。然后如果它被获取,将处理下一行并显示 Point
。
<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
}
这行得通吗?
private void Button_Click(object sender, RoutedEventArgs e)
{
this.PreviewMouseLeftButtonDown += MainWindow_PreviewMouseLeftButtonDown;
}
private void MainWindow_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.PreviewMouseLeftButtonDown -= MainWindow_PreviewMouseLeftButtonDown;
Point point = e.GetPosition(this);
MessageBox.Show(point.ToString());
e.Handled = true;
}
你不需要使用"this",我只是喜欢使用它,不确定它是否是一个好的做法。
的解决方案
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;
}
}
我希望当用户点击 Button
时,程序等待用户点击 Window
并且不会继续执行下一行代码,除非 Point
通过单击 Window
获取。然后如果它被获取,将处理下一行并显示 Point
。
<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
}
这行得通吗?
private void Button_Click(object sender, RoutedEventArgs e)
{
this.PreviewMouseLeftButtonDown += MainWindow_PreviewMouseLeftButtonDown;
}
private void MainWindow_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.PreviewMouseLeftButtonDown -= MainWindow_PreviewMouseLeftButtonDown;
Point point = e.GetPosition(this);
MessageBox.Show(point.ToString());
e.Handled = true;
}
你不需要使用"this",我只是喜欢使用它,不确定它是否是一个好的做法。
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;
}
}