Как перетащить UserControl в Canvas

Это то же самое, INTO полностью необязательно в T-SQL (другие диалекты SQL могут отличаться).

Вопреки другим ответам, я думаю, что это ухудшает читаемость INTO .

Я думаю, что это концептуальная вещь. По моему мнению, я не вставляю строку в таблицу с именем «Клиент», но я вставляю Customer . (Это связано с тем, что я использую для обозначения своих таблиц в единственном числе, а не во множественном числе).

Если вы будете следовать первому понятию, INSERT INTO Customer, скорее всего, «чувствует себя хорошо» для вас.

Если вы следуете второй концепции, это, скорее всего, будет INSERT Customer для вас.

13
задан Dave Clemmer 18 August 2011 в 03:25
поделиться

2 ответа

Это делается в silverlight, а не в WPF, но должно работать так же.

Создайте два частных свойства для элемента управления:

protected bool isDragging;  
private Point clickPosition;

Затем прикрепите некоторые обработчики событий в конструкторе элемент управления:

this.MouseLeftButtonDown += new MouseButtonEventHandler(Control_MouseLeftButtonDown);
this.MouseLeftButtonUp += new MouseButtonEventHandler(Control_MouseLeftButtonUp);
this.MouseMove += new MouseEventHandler(Control_MouseMove);

Теперь создайте эти методы:

private void Control_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    isDragging = true;
    var draggableControl = sender as UserControl;
    clickPosition = e.GetPosition(this);
    draggableControl.CaptureMouse();
}

private void Control_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    isDragging = false;
    var draggable = sender as UserControl;
    draggable.ReleaseMouseCapture();
}

private void Control_MouseMove(object sender, MouseEventArgs e)
{
    var draggableControl = sender as UserControl;

    if (isDragging && draggableControl != null)
    {
        Point currentPosition = e.GetPosition(this.Parent as UIElement);

        var transform = draggableControl.RenderTransform as TranslateTransform;
        if (transform == null)
        {
            transform = new TranslateTransform();
            draggableControl.RenderTransform = transform;
        }

        transform.X = currentPosition.X - clickPosition.X;
        transform.Y = currentPosition.Y - clickPosition.Y;
    }
}

Здесь следует отметить несколько моментов:
1. Это не обязательно должно быть на холсте. Это может быть стековая панель или сетка.
2. Это делает весь элемент управления перетаскиваемым, это означает, что если вы щелкните в любом месте элемента управления и перетащите его, он перетащит весь элемент управления. Не уверен, что это именно то, что вам нужно.

Edit-
Расширяя некоторые особенности вашего вопроса: Лучший способ реализовать это - создать класс, унаследованный от UserControl, который может называться DraggableControl, созданный с помощью этого кода, тогда все перетаскиваемые элементы управления должны расширять DraggableControl.

Редактировать 2 - Есть небольшая проблема, когда у вас есть сетка данных в этом элементе управления. Если вы отсортируете столбец в сетке данных, событие MouseLeftButtonUp никогда не сработает. Я обновил код, поэтому isDragging защищен. Я нашел лучшее решение - связать этот анонимный метод с событием LostMouseCapture в сетке данных:

this.MyDataGrid.LostMouseCapture += (sender, e) => { this.isDragging = false; };
40
ответ дан 1 December 2019 в 06:59
поделиться

Если кто-то хочет быстро видеть этот эффект, вот минимальное решение с помощью только MouseMove событие.

Расположение

<Canvas Background='Beige'
            Name='canvas'>
        <Rectangle Width='50'
                   Height='50'
                   Fill='LightPink'
                   Canvas.Left='350'
                   Canvas.Top='175'
                   MouseMove='Rectangle_MouseMove' />
    </Canvas>

Код позади

 private void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (e.Source is Shape shape)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    Point p = e.GetPosition(canvas);
                    Canvas.SetLeft(shape, p.X - shape.ActualWidth / 2);
                    Canvas.SetTop(shape, p.Y - shape.ActualHeight / 2);
                    shape.CaptureMouse();
                }
                else
                {
                    shape.ReleaseMouseCapture();
                }
            }
        }
1
ответ дан 1 December 2019 в 06:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: