Перетаскиваемый всплывающий элемент управления в wpf - PullRequest
4 голосов
/ 24 января 2011

Мне нужен перетаскиваемый элемент управления всплывающими окнами в wpf, и мне было интересно, сможет ли кто-нибудь из ваших парней мне помочь.

Drag WPF Popup control

но это не так, как это должно работать ...? Когда я нажимаю и перетаскиваю, он всегда сбрасывается в определенную точку, и, кроме того, комментаторы говорят, что это не эффективный подход ...? У кого-нибудь есть альтернативы?

Спасибо!

Ответы [ 2 ]

15 голосов
/ 24 января 2011

Мы можем написать поведение, чтобы сделать любой Popup перетаскиваемым.Вот пример XAML всплывающего окна, связанного с текстовым полем, которое открывается и остается открытым, когда текстовое поле находится в фокусе:

<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>

Вот поведение, которое позволяет нам перетащить 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();
        };
    }
}

Если вы не знакомы с поведением, установите Expression Blend 4 SDK и добавьте следующие пространства имен:

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

и добавьте System.Windows.Interactivity в ваш проект.

0 голосов
/ 24 января 2011

Вы можете открыть дочернее окно с пользовательским макетом границы.Затем добавьте обработчик MouseDown, который включает перетаскивание:

<Window 
        WindowStyle="None"
        ShowInTaskbar="False"
        ResizeMode="NoResize"
        SizeToContent="Height"
        MouseDown="Window_MouseDown">
...
</Window>

В коде позади:

    private void Window_MouseDown(Object sender, MouseButtonEventArgs e)
    {
        this.DragMove();
    }
...