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?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage