Перетаскиваемый всплывающий элемент управления в wpf

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

Перетащите элемент управления всплывающим окном WPF

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

Спасибо!


person Dan    schedule 24.01.2011    source источник
comment
как говорится в связанном вопросе, вам, вероятно, следует использовать Thumb вместо всплывающего окна   -  person Robert Levy    schedule 24.01.2011
comment
Можно ли с помощью большого пальца перемещать всплывающее окно при перемещении мыши...? Я так не думаю.. насколько я знаю...? у вас есть пример того, как мы могли бы использовать большой палец для перетаскивания? Благодарность! извините, я новичок в wpf... так что если мои вопросы покажутся глупыми... прошу прощения... :)   -  person Dan    schedule 24.01.2011


Ответы (2)


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

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

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

    private void Window_MouseDown(Object sender, MouseButtonEventArgs e)
    {
        this.DragMove();
    }
person matthias.lukaszek    schedule 24.01.2011
comment
Спасибо, Матиас ... хорошее предложение ... если я не могу заставить всплывающее окно перетаскиваться, я думаю, я воспользуюсь вашим решением. - person Dan; 24.01.2011
comment
Как установить положение окна относительно определенного элемента управления и разрешить его перетаскивание только в пределах границ другого окна? - person Dan; 24.01.2011
comment
Позиционирование окна должно быть возможно путем установки Window.Left и Window.Top после определения положения с помощью PointToScreen(...). Я не знаю, как прикрепить его к другому окну. - person matthias.lukaszek; 24.01.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 в свой проект.

person Rick Sladkey    schedule 24.01.2011
comment
Это простое упражнение — заставить функцию использовать код программной части вместо этого. Просто добавьте обработчики и измените AssociatedObject на popup1. - person Rick Sladkey; 24.01.2011
comment
о, хорошо, круто ... Так что мне просто нужно заменить поведение соответствующими событиями mouseup mousedown в коде, не так ли? (заменив AssociatedObject на popup1) Спасибо! - person Dan; 24.01.2011