2014-12-24 7 views
0

Я рисую прямоугольную панель с каждой кнопкой. После этого добавьте строку на краю прямоугольника и текст по центру. Но когда я перетаскиваю панель на другую панель. Строка панели изменится. Пожалуйста посоветуй. Я не могу загрузить изображение. Как я могу загрузить изображение, подобное этому, может показать мою проблему более четко.Drawstring на панели меняются, когда другая панель перемещается над

Эта ссылка http://i3.photobucket.com/albums/y53/ctkhai/1-4.png показать gui моего программного обеспечения. В верхнем левом и нижнем левом углу расположены рамки. Пользователь добавляет «поле», когда нажимает кнопку один раз, и «поле» будет отображаться в левом верхнем углу. Пользователь может перетащить ящик в нижний правый угол и упорядочить все поля.

проблема заключается в том, что пользователь перетаскивает новый добавленный «ящик» и перемещается по другому «ящику», текст, который я рисую на предыдущем поле, будет меняться. как это http://i3.photobucket.com/albums/y53/ctkhai/2-4.png.

Обновление: Я пытаюсь создать класс для тега. но это не сработает, число снова изменится. Это способ создания класса для тега, а чтение неверно? код, как показано ниже

Product _box = new Product(); 
List<Panel>product = new List<Panel>(); 

public class Product 
{   
    public float X { set; get; }  //box coordinate 
    public float Y { set; get; }  //box coordinate 
    public int rotate { set; get; } 
    public int entryP { set; get; } 
    public int boxName { set; get; } 

} 

private void button_RecAdd_Click(object sender, EventArgs e) 
{ 


    locX = pictureBox_conveyor.Left + (pictureBox_conveyor.Width/2 - box_y/2); 
    locY = pictureBox_conveyor.Top + (pictureBox_conveyor.Height/2 - box_x/2); 

    _box.boxName = panelBoxNo; 
    _box.entryP = 1; 
    _box.rotate = 0; 
    _box.X = locX; 
    _box.Y = locY; 


    Panel box = new Panel(); 
    box.Location = new Point(locX, locY); 
    box.Name = "box" + panelBoxNo; 
    box.Tag = _box; 
    box.Size = new Size(box_y, box_x); 
    box.BackColor = boxColor; 
    pbW = box.Width; 
    pbH = box.Height; 
    box.MouseDown += panelBox_MouseDown; 
    box.MouseMove += panelBox_MouseMove;    


    box.Paint += new PaintEventHandler((s, m) => 
    { 

     Graphics g = m.Graphics; 
     g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;] 

     Product b = box.Tag as Product; 

     string text = b.boxName.ToString(); 

     SizeF textSize = m.Graphics.MeasureString(text, Font); 
     PointF locationToDraw = new PointF(); 
     locationToDraw.X = (pbW/2) - (textSize.Width/2); 
     locationToDraw.Y = (pbH/2) - (textSize.Height/2); 

     g.DrawString(text, Font, Brushes.Black, locationToDraw); 
     g.DrawRectangle(new Pen(Color.Black), 0, 0, pbW - 1, pbH - 1); 
     g.DrawLine(drawLine, 0, 0, 0, pbH);      

    }); 

    product.Add(box); 
    panel_pelletLayout.Controls.Add(box); 
    box.BringToFront(); 
    label_boxNo.Text = panelBoxNo.ToString(); 
    panelBoxNo++; 

} 

private void panelBox_MouseDown(object sender, MouseEventArgs e) 
    { 
     Panel p = sender as Panel; 

     if (e.Button == MouseButtons.Left) 
     { 
      xPos = e.X; 
      yPos = e.Y; 

      if (p != null) 
      { 
       activePnlBox = p.Name;          
       textBox_selectedName.Text = p.Name;      
       textBox_selectedX.Text = p.Left.ToString(); 
       textBox_selectedY.Text = p.Top.ToString(); 

      } 
     } 
    } 

private void panelBox_MouseMove(object sender, MouseEventArgs e) 
    { 
     Panel p = sender as Panel;  

     if (p != null) 
     { 

      if (e.Button == MouseButtons.Left) 
      { 

       p.Left = ((e.X + p.Left - (p.Width/2))/gripGap) * gripGap;      
       p.Top = ((e.Y + p.Top - (p.Height/2))/gripGap) * gripGap; 

       textBox_selectedX.Text = p.Left.ToString(); 
       textBox_selectedY.Text = p.Top.ToString(); 

      }   
     } 
    } 
+0

Загрузить изображение где-нибудь еще и поделиться ссылкой, я добавлю его в вашем после. –

+0

Можете ли вы разместить обработчики mouseDown и mouseMove тоже –

+0

Привет @TaW, но мне нужно, чтобы пользователь добавил несколько ящиков с нажатием кнопки, после чего перегруппируйте поле. проблема в том, что не знаю, сколько добавит пользователь box. –

ответ

0

Ваш титул получил все из нас запутался .. Вы не рисовать прямоугольники, вы создавать новые панели на каждом ButtonClick, верно?

Код для Paint Событие не совсем верно. Как и в любом случае Paint, вы должны использовать встроенный объект Graphics. И как отметил Ханс, вы не должны уничтожать/уничтожать вещи, которые вы не создали.

Основная проблема, которую вы описываете, состоит в том, что ваши коробки должны рисовать сами, не ссылаясь на их реальные числа. Вы должны хранить их номера, например. в их Tags ..

(Или вы могли бы извлечь из их Names, как вы делаете это в MouseDown!)

box[panelBoxNo].Name = "box" + panelBoxNo; 
box[panelBoxNo].Tag = panelBoxNo;      // < === !! 
//.. 

box[panelBoxNo].Paint += new PaintEventHandler((s, m) => 
{ 
    Graphics g = m.Graphics;       // < === !! 
    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; 
    string text = box[panelBoxNo].Tag.ToString();  // < === 
    SizeF textSize = g.MeasureString(text, Font); 
    PointF locationToDraw = new PointF(); 
    locationToDraw.X = (pbW/2) - (textSize.Width/2); 
    locationToDraw.Y = (pbH/2) - (textSize.Height/2); 

    g.DrawString(text, Font, Brushes.Black, locationToDraw); 
    g.DrawRectangle(new Pen(Color.Black), 0, 0, pbW - 1, pbH - 1); 
    g.DrawLine(drawLine, 0, 0, 0, pbH); 
    // g.Dispose();      // < === !! 

    // m.Graphics.DrawImageUnscaled(drawBox, new Point(0, 0));   // < === !! 
    // m.Dispose();      // < === !! 
}); 

И, как я уже отметил, следует использовать только массивы, если вы (или код) действительно знает количество элементов. В вашем случае List<Panel> будет гибким для хранения любого количества элементов без изменения какой-либо другой части кода, кроме добавления. Вы можете получить доступ к Списку так же, как массив. (Что это за кулисами ..)

Update: Как я вижу это сейчас, ваши проблемы все о сфера в той или иной форме.

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

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

Ваша текущая проблема заключается в понимании области действия переменных в событии ButtonClick.

Обычно это не проблема; глядя на пары фигурных скобок, масштаб очевиден. Но: Здесь у нас есть динамически созданное событие Lambda, и это полностью выходит за рамки события Click! За кулисами это событие Paint удаляется из кода Click, помещается в новое событие и заменяется линией, которая просто добавляет делегат в обработчик Paint так же, как любое регулярное событие.

Итак: ничего вы объявляете в ButtonClick не известно в Paint коде!

Чтобы получить доступ к этим данным необходимо поместить их в Panel properties, в нашем случае в Tag и доступ к ним с помощью литья из параметра sSender!

Таким образом, вы должны изменить эту строку в случае Paint

Product b = box.Tag as Product; 

к чему-то вроде этого:

Product b = ((Panel) s).Tag as Product; 
+0

Привет @TaW, Да, я меняю массив на список уже благодаря большому количеству ящиков, только одна из проблем. чтобы повернуть коробку так, чтобы красная линия окна тоже попала в ту же проблему. Попробуй TAG позже. Спасибо –

+0

Спасибо @Taw, теги, которые вы сказали, работают. Теперь красная строка окна имеет ту же проблему, когда я повернуть его. http://i3.photobucket.com/albums/y53/ctkhai/3-1.png, http://i3.photobucket.com/albums/y53/ctkhai/4.png. Пожалуйста, совет –

+0

И о класс «Продукт», в любом случае, чтобы класс стал массивом, а не объявлял весь член класса массивом? Большое спасибо. –

1

Ваш обработчик события Paint должен отвечать за рисование всего каждый раз. Ваш код выглядит так, будто он рисует только один объект.

Когда вы перетаскиваете что-то поверх своего box, коробка становится недействительной и должна быть окрашена с нуля, что означает, что она удаляет все и вызывает ваш обработчик Paint. Затем обработчик события Paint просто рисует один объект.

Я подозреваю, что то, что вы хотите сделать, это сохранить структуру данных каждого элемента, который вы рисуете, а затем создать цикл в обработчике событий Paint, который будет рисовать все объекты, которые вы добавляете.

+0

Привет, Брэд Рем, это значит, что мне нужно нарисовать весь объект, когда я перемещаю «ящик»? Я назначаю событие paint для окна box box [panelBoxNo] .Paint + = new PaintEventHandler ((s, m). Это означает, что всякий раз, когда я перемещаю новый «ящик», я просто перерисовываю весь элемент внутри поля «panelBoxNo» »? –

+0

Или есть ли какой-либо метод, чтобы предотвратить «ящик» недействительным, когда другая панель над ним? Спасибо –

1

Не используйте переменные, которые вы определили вне цикла, в событии рисования. Это может быть вашей проблемой. Постарайтесь нарисовать ((Panel)s).Name. Правильно ли это работает?