So können Sie ein Benutzersteuerelement wie ein Fenster auf dem Bildschirm ziehen
Meine WPF-Anwendung hat eineUserControl
Das soll wie ein Popup-Fenster aussehen und sich so verhalten, aber es ist kein Fenster. Der Grund, warum das Steuerelement nicht von der abgeleitet istWindow
Klasse ist, weil es eine virtuelle Bildschirmtastatur eines Drittanbieters enthält, und dieses Steuerelement muss sich im selben Fenster wie das befindenTextBox
Steuert, dass Eingabezeichen gesendet werden, wenn Sie auf die Schaltflächen klicken. Befindet sich die Tastatursteuerung nicht im selben Fenster, kann sie nicht einmal das sehenTextBox
Kontrollen.
Das Problem, das ich habe, ist Leistung ist miserabel, wenn ich den Dialog herum ziehe. Es ist ausreichend langsam, dass sich die Maus vom Ziehbereich löst und nicht mehr der Maus folgt. Ich brauche einen besseren Weg.
Hier ist ein Auszug aus dem XAML zur Kontrolle:
<Grid Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Background="{DynamicResource PopupBackground}"
BorderBrush="{DynamicResource PopupBorder}"
BorderThickness="5,5,5,0"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
MouseMove="Grid_MouseMove">
. . .
</Border>
</Grid>
Hier sind die Maus-Event-Handler:
private void Grid_MouseLeftButtonDown( object sender, MouseButtonEventArgs e ) {
Canvas canvas = Parent as Canvas;
if ( canvas == null ) {
throw new InvalidCastException( "The parent of a KeyboardPopup control must be a Canvas." );
}
DraggingControl = true;
CurrentMousePosition = e.GetPosition( canvas );
e.Handled = true;
}
private void Grid_MouseLeftButtonUp( object sender, MouseButtonEventArgs e ) {
Canvas canvas = Parent as Canvas;
if ( canvas == null ) {
throw new InvalidCastException( "The parent of a KeyboardPopup control must be a Canvas." );
}
if ( DraggingControl ) {
Point mousePosition = e.GetPosition( canvas );
// Correct the mouse coordinates in case they go off the edges of the control
if ( mousePosition.X < 0.0 ) mousePosition.X = 0.0; else if ( mousePosition.X > canvas.ActualWidth ) mousePosition.X = canvas.ActualWidth;
if ( mousePosition.Y < 0.0 ) mousePosition.Y = 0.0; else if ( mousePosition.Y > canvas.ActualHeight ) mousePosition.Y = canvas.ActualHeight;
// Compute the new Left & Top coordinates of the control
Canvas.SetLeft( this, Left += mousePosition.X - CurrentMousePosition.X );
Canvas.SetTop( this, Top += mousePosition.Y - CurrentMousePosition.Y );
}
e.Handled = true;
}
private void Grid_MouseMove( object sender, MouseEventArgs e ) {
Canvas canvas = Parent as Canvas;
if ( canvas == null ) {
// It is not. Throw an exception
throw new InvalidCastException( "The parent of a KeyboardPopup control must be a Canvas." );
}
if ( DraggingControl && e.LeftButton == MouseButtonState.Pressed ) {
Point mousePosition = e.GetPosition( canvas );
// Correct the mouse coordinates in case they go off the edges of the control
if ( mousePosition.X < 0.0 ) mousePosition.X = 0.0; else if ( mousePosition.X > canvas.ActualWidth ) mousePosition.X = canvas.ActualWidth;
if ( mousePosition.Y < 0.0 ) mousePosition.Y = 0.0; else if ( mousePosition.Y > canvas.ActualHeight ) mousePosition.Y = canvas.ActualHeight;
// Compute the new Left & Top coordinates of the control
Canvas.SetLeft( this, Left += mousePosition.X - CurrentMousePosition.X );
Canvas.SetTop ( this, Top += mousePosition.Y - CurrentMousePosition.Y );
CurrentMousePosition = mousePosition;
}
e.Handled = true;
}
Beachten Sie, dass das Steuerelement in a platziert werden mussCanvas
in dem Fenster, das es verwendet.
Ich kann nicht verwendenDragMove
wie es ist eine Methode derWindow
Klasse und diese Klasse stammt ab vonUserControl
. Wie verbessere ich die Leistung beim Ziehen dieses Steuerelements? Muss ich auf Win32-APIs zurückgreifen?