Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A draggable popup control in wpf

I need a draggable popup control in wpf and was wondering if any of your guys could help me out..I did see the following post:

Drag WPF Popup control

but that isnt how its supposed to work...? When i click and drag it always resets to a specific point and moreover the commenters said that this is not an efficient approach...? Does anyone have any alternatives?

Thanks!

like image 783
Dan Avatar asked Dec 04 '22 09:12

Dan


1 Answers

We can write a behavior to make any Popup draggable. Here is some sample XAML of a popup associated with a textbox that opens and stays open when the text box is focused:

<Grid>
    <StackPanel>
        <TextBox x:Name="textBox1" Width="200" Height="20"/>
    </StackPanel>
    <Popup PlacementTarget="{Binding ElementName=textBox1}" IsOpen="{Binding IsKeyboardFocused, ElementName=textBox1, Mode=OneWay}">
        <i:Interaction.Behaviors>
            <local:MouseDragPopupBehavior/>
        </i:Interaction.Behaviors>
        <TextBlock Background="White">
            <TextBlock.Text>Sample Popup content.</TextBlock.Text>
        </TextBlock>
    </Popup>
</Grid>

Here is the behavior that allows us to drag the Popup:

public class MouseDragPopupBehavior : Behavior<Popup>
{
    private bool mouseDown;
    private Point oldMousePosition;

    protected override void OnAttached()
    {
        AssociatedObject.MouseLeftButtonDown += (s, e) =>
        {
            mouseDown = true;
            oldMousePosition = AssociatedObject.PointToScreen(e.GetPosition(AssociatedObject));
            AssociatedObject.Child.CaptureMouse();
        };
        AssociatedObject.MouseMove += (s, e) =>
        {
            if (!mouseDown) return;
            var newMousePosition = AssociatedObject.PointToScreen(e.GetPosition(AssociatedObject));
            var offset = newMousePosition - oldMousePosition;
            oldMousePosition = newMousePosition;
            AssociatedObject.HorizontalOffset += offset.X;
            AssociatedObject.VerticalOffset += offset.Y;
        };
        AssociatedObject.MouseLeftButtonUp += (s, e) =>
        {
            mouseDown = false;
            AssociatedObject.Child.ReleaseMouseCapture();
        };
    }
}

If you are not familiar with behaviors, install the Expression Blend 4 SDK and add this namespaces:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

and add System.Windows.Interactivity to your project.

like image 198
Rick Sladkey Avatar answered Dec 28 '22 04:12

Rick Sladkey