Как нарисовать выбираемую линию?

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

заранее спасибо


Мне удалось сделать это, используя жестко закодированный прямоугольник. Но я до сих пор не знаю, как это сделать с помощью drawLine() Могу ли я использовать drawPath для проверки попаданий?

Вот код:

private bool selectGraph = false;
private Rectangle myrec = new Rectangle(50, 50, 100, 100);
private Graphics g;

private void panel1_Paint(object sender, PaintEventArgs e)
    {
        SolidBrush sb = new SolidBrush(Color.Blue);
        Pen p = new Pen(Color.Blue, 5);

        e.Graphics.DrawRectangle(p, myrec);
        e.Graphics.FillRectangle(sb, myrec);
    }

    private void panel1_MouseUp(object sender, MouseEventArgs e)
    {
        Point mPT = new Point(e.X, e.Y);

        if (e.Button == MouseButtons.Left)
        {
            if (myrec.Contains(mPT))
            {
                selectGraph = true;
                button1.Enabled = true;
            }
            else
            {
                selectGraph = false;
                button1.Enabled = false;
            }
        }
        Invalidate();
    }

person Rye    schedule 29.08.2010    source источник
comment
Дерьмо, есть инструменты VisualBasic Powerpack.   -  person Rye    schedule 31.08.2010
comment
Пожалуйста, о, пожалуйста, избавьтесь от этой строки g = panel1.CreateGraphics();! Вы уже находитесь в обработчике событий Paint. У PaintEventArgs есть свойство Graphics, которое вы используете для рисования. Ваше приложение будет медленным и крайне глючным, если вы будете использовать текущий способ. :)   -  person TheCloudlessSky    schedule 31.08.2010
comment
@TheClodlessSky да, я уже стер такой подход! Я новичок в GDI, поэтому, лол. Спасибо ТКС :)   -  person Rye    schedule 31.08.2010


Ответы (2)


Ну, вы могли бы начать с чего-то вроде простого класса Line:

public class Line
{
    public Point Start { get; set; }
    public Point End { get; set; }
}

Тогда вы можете иметь свою форму:

private Line Line = new Line();

protected override void OnPaint(PaintEventArgs e)
{
    e.Graphics.DrawLine(Pens.Red, this.Line.Start, this.Line.End);
}

protected override void OnMouseMove(MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        this.Line.Start = e.Location;
        this.Refresh();
    }
    else if (e.Button == MouseButtons.Right)
    {
        this.Line.End = e.Location;
        this.Refresh();
    }
}

Таким образом, в основном они могли бы удалить this.Line, возможно, по щелчку «MiddleButton» или что-то в этом роде. Этого должно быть достаточно, чтобы вы начали.

Я создал пример, показывающий, как это можно сделать. Установите несколько точек останова и посмотрите, как все делается.

person TheCloudlessSky    schedule 30.08.2010
comment
Это происходит при перемещении мыши. Я хочу, чтобы, когда линия уже находится в событии рисования, я мог перетаскивать, выбирать и удалять ее. Подобно перетаскиванию пользовательского элемента управления Visual Studio. Когда пользователь добавляет, например, кнопку, он может перемещать ее по форме. - person Rye; 30.08.2010
comment
@Rye - Хорошо, но то, что я вам предоставил, является основой для начала работы. Перетаскивание — это в основном MouseMove при нажатии кнопки. Если вы хотите перетащить линию, вам нужно сместить точки Start и End. Если вы хотите удалить его, вы можете установить Line в NULL. - person TheCloudlessSky; 30.08.2010
comment
Да да, но моя основная проблема заключается в выборе строки. - person Rye; 30.08.2010
comment
@Rye - вы должны реализовать выбор строки. Например, OnClick может взять e.Location и посмотреть, находится ли он в пределах 10 пикселей от линии, если да, то выбрать линию (вы можете установить Selected=true для объекта Line), а затем перерисовать. OnPaint мог сказать if Line is selected, draw it red, otherwise, black. Этого должно быть более чем достаточно для начала. - person TheCloudlessSky; 30.08.2010
comment
Ах, это означает, что на него можно щелкнуть, используя положение графического объекта. Хорошая идея. - person Rye; 31.08.2010
comment
@ Рай - да. Вы выполняете всю свою логику перемещения и т. д. в обработчиках событий Mouse, а затем вызываете Refresh(), чтобы перерисовать элемент управления. Затем используйте OnPaint для обработки. Нет концепции выбора и объекта, вам нужно создать эту идею самостоятельно. - person TheCloudlessSky; 31.08.2010
comment
@TCS Это очень полезно! Спасибо за это. Ваши комментарии тоже великолепны, они помогают мне быстро понять код. :) - person Rye; 01.09.2010
comment
Привет, @TCS, просто хочу поблагодарить тебя за образец программы, который ты мне дал. это мне очень помогает. Ты лучший :) Ура! - person Rye; 22.09.2010
comment
@TheCloudlessSky Здравствуйте, я пытаюсь решить ту же проблему, и я попытался загрузить образец (по ссылке sendspace). Однако, похоже, загружается какой-то ненужный файл. Любой шанс, что у вас все еще есть образец. - person Win Coder; 27.06.2013
comment
@WinCoder - Хм... кажется, SendSpace изменил ссылку на что-то другое. У меня нет образца. Но я собрал для вас образец Gist: gist.github.com/TheCloudlessSky/5880943 - person TheCloudlessSky; 28.06.2013

Для этого нет простого однострочного решения. Вы должны были бы запрограммировать это самостоятельно.

Вы должны отслеживать каждый объект, который вы нарисовали. В событии onmousedown вы должны выяснить, щелкнула ли мышь на объекте, который вы хотите переместить/удалить, или рядом с ним, сравнивая координаты. Затем вам нужно нарисовать какое-то визуальное руководство, что линия «выбрана». Удалить теперь довольно просто, удалив объект из коллекции.

Для перетаскивания вам нужно сделать что-то подобное, изменив координаты объекта в соответствии с движением мыши.

person Ikke    schedule 30.08.2010
comment
Знаете ли вы некоторые ссылки, которые я могу использовать для справки? - person Rye; 30.08.2010