Рисуя много эллипсов и выбрав их для удаления с помощью C # WinformsApp [duplicate]

Программа для интерфейса позволяет легко изменять реализацию контракта, определяемого интерфейсом. Он позволяет свободно связываться между контрактом и конкретными реализациями.

IInterface classRef = new ObjectWhatever()

Вы можете использовать любой класс, который реализует IInterface? Когда вам это нужно?

blockquote>

Взгляните на этот вопрос SE на хорошем примере.

Почему должен быть предпочтительным интерфейс для класса Java?

использует ли производительность интерфейса?

if так сколько?

blockquote>

Да. В субсекундах он будет иметь незначительные эксплуатационные издержки. Но если ваше приложение требует динамического изменения интерфейса, не беспокойтесь о влиянии производительности.

как вы можете избежать этого, не имея необходимости поддерживать два бита кода?

blockquote>

Не пытайтесь избежать нескольких реализаций интерфейса, если ваше приложение нуждается в них , В отсутствие жесткой связи интерфейса с одной конкретной реализацией вам может потребоваться развернуть патч, чтобы изменить одну реализацию на другую реализацию.

Один хороший вариант использования: реализация шаблона стратегии:

Реальный мир Пример шаблона стратегии

2
задан TaW 3 October 2015 в 09:42
поделиться

2 ответа

Вот подходящий класс Line:

class Line
{
    public Color LineColor { get; set; }
    public float Linewidth { get; set; }
    public bool Selected { get; set; }
    public Point Start { get; set; }
    public Point End { get; set; }

    public Line(Color c, float w, Point s, Point e)
    { LineColor = c; Linewidth = w; Start = s; End = e;    }

    public void Draw(Graphics G)
    { using (Pen pen = new Pen(LineColor, Linewidth)) G.DrawLine(pen, Start, End); }

    public bool HitTest(Point Pt)
    {
        // test if we fall outside of the bounding box:
        if ((Pt.X < Start.X && Pt.X < End.X) || (Pt.X > Start.X && Pt.X > End.X) ||
            (Pt.Y < Start.Y && Pt.Y < End.Y) || (Pt.Y > Start.Y && Pt.Y > End.Y)) 
            return false;
        // now we calculate the distance:
        float dy = End.Y - Start.Y;
        float dx = End.X - Start.X;
        float Z = dy * Pt.X - dx * Pt.Y + Start.Y * End.X - Start.X * End.Y;
        float N = dy * dy + dx * dx;
        float dist = (float)( Math.Abs(Z) / Math.Sqrt(N));
        // done:
        return dist < Linewidth / 2f;
    }

}

Определите список строк, возможно, на уровне класса:

    List<Line> lines = new List<Line>();

Вот как вы можете инициализировать это несколько строк:

for (int i = 0; i < 20; i++) lines.Add(new Line(Color.Black, 4f, 
    new Point(R.Next(panel1.Width), R.Next(panel1.Height)), 
    new Point(R.Next(panel1.Width), R.Next(panel1.Height))));

Вот результат нажатия на переход:

Всякий раз, когда вы добавляете , измените или удалите строку, необходимую для того, чтобы Panel отразили новости, вызвав событие Paint:

panel1.Invalidate();

. Здесь Paint событие Panel:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    foreach (Line L in lines) L.Draw(e.Graphics);
}

В событии MouseClick вы выполните тест:

private void panel1_MouseClick(object sender, MouseEventArgs e)
{
    foreach(Line L in lines) 
            L.LineColor = L.HitTest(e.Location) ?  Color.Red : Color.Black;
    panel1.Invalidate();
}

Чтобы избежать мерцания, не используйте базовый класс Panel, поскольку он не doublebuffered , Вместо этого используйте либо подкласс PictureBox, либо doublebuffered Panel:

class DrawPanel : Panel 
{     public DrawPanel ()   { DoubleBuffered = true; }   }

Примечания:

  • В WinForms нет такой вещи, как «Линия», только пикселей различных цветов. Поэтому, чтобы выбрать строку, вам нужно сохранить координаты двух конечных точек, а затем выяснить, попали ли вы при нажатии.
  • В приведенном выше примере показано, как это сделать в математике.
  • Вместо этого можно проверить каждую строку, нарисуя ее на растровое изображение и протестировать пиксель, щелкнув мышью. Но рисование этих растровых изображений должно было бы выполнять математику за кулисами, а также выделять пространство для растровых изображений, поэтому математика будет более эффективной ..
  • Да, класс Line выглядит немного длиннее для таких простая вещь asa line, но посмотрите, насколько короткими все коды событий теперь! Это потому, что ответственность - это место, где они принадлежат!
  • Также обратите внимание, что первое правило делать любой рисунок в WinForms: Никогда не кэшируйте или не храните объект Grahics. Фактически, вы никогда не должны использовать CreateGraphics в первую очередь, так как объект Graphics никогда не останется в области видимости, и создаваемая графика не будет сохраняться (т. Е. Выдержать последовательность с минимальным увеличением).
  • Также обратите внимание, как я передаю e.Graphics объект параметров события Paint в экземпляры Line, чтобы они могли нарисовать себя с помощью текущего объекта Graphics!
  • Чтобы выбрать более тонкий линии, это может помочь немного изменить проверку расстояния ..
  • Математика была взята непосредственно из Wikipedia .
6
ответ дан TaW 20 August 2018 в 20:33
поделиться
  • 1
    Благодаря! это объясняет все и отлично работает – Kancil 7 October 2015 в 09:19
  • 2
    Можно ли изменить этот код, чтобы удалить выбранную строку? – CodexVideos 18 April 2016 в 10:03
  • 3
    Конечно. Он находится в List<T>, поэтому, как только вы его нашли, вы можете сделать lines.Remove(foundLine). – TaW 18 April 2016 в 14:01

Вы можете изменить цвет всего на клик. Используя событие click для конкретного объекта.

Я даю вам пример для кнопки. Если вы нажмете кнопку, то цвет паники будет изменен. Вы можете изменить код в соответствии с вашим требованием.

private List<Point> coordFirst = new List<Point>();
    private List<Point> coordLast = new List<Point>();
    public Graphics canvas;



    private void Form1_Load(object sender, EventArgs e)
    {
        canvas = panel1.CreateGraphics();
    }





    private void panel1_Click(object sender, EventArgs e)
    {
        panel1.BackColor = Color.Blue;
    }

    private void nonSelectableButton3_Click(object sender, EventArgs e)
    {
        panel1.BackColor = Color.BurlyWood;
    }
-1
ответ дан Muhammed Naqi 20 August 2018 в 20:33
поделиться
  • 1
    Не панель backcolor, но изменение цвета строки (если выбрана линия) – Kancil 3 October 2015 в 07:28
Другие вопросы по тегам:

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