2015-02-23 3 views
-1

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

http://postimg.org/image/d8p4s53pf/

EDIT:

Попытка сделать PictureBox поистине транспарант. Материал перетаскивания выполнен, но фон - это только фон панели и не отображает элементы управления, которые он передает.

Я использовал это, но это немного глючит.

protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cp = base.CreateParams; 
      cp.ExStyle = 0x00000020; //WS_EX_TRANSPARENT 
      return cp; 
     } 
    } 

    protected override void OnPaintBackground(PaintEventArgs pevent) 
    { 
     //do nothing 
    } 

    protected override void OnMove(EventArgs e) 
    { 
     RecreateHandle(); 
    } 
+0

Это не очень понятно, что вы просите. Вы хотите знать, как сделать ваши pngs прозрачными, или как сделать ваши изображения перетаскиваемыми? – thomasb

+0

Прозрачность прозрачности - это взлом, и он просто принимает цвет того, что стоит за ним ... Если вы разместите ссылку на изображение, кто-то сможет отредактировать изображение на ваш вопрос, который может сделать ваш вопрос более ясным – Sayse

+0

Это будет не работа. Для шахматной доски подумайте об установке всей доски в панели «Паттерн» (или «Изображение») и «Нанесение фигур на поверхность». Затем вы можете использовать __one__ PictureBox, который находится внутри панели, пока вы рисуете или, что более естественно, просто обновляете положение движущегося элемента в mousemove. Для этого вам нужно поместить движущуюся деталь в качестве последней части в ваш список предметов, поэтому она всегда нарисована сверху. – TaW

ответ

0

Dragable Controls как таковые не трудно в WinForms. Но как только они нуждаются в прозрачности варианты довольно ограничены: каждый должен полностью содержаться в его Parent; это означает, что все они должны быть вложенными. Нет проблем с созданием набора прозрачных слоев, как в графической программе.

Но перемещение даже одинPictureBox-Pawn через борт, полный других просто не будет работать с WinForms Controls.

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

Вместо этого вы можете просто нарисовать шахматные фигуры на поверхности управления в событии Paint. Я реализовал элементарное решение, и вот на Paint событие от него:

List<ChessPiece> pieces = new List<ChessPiece>(); 
int mpIndex = -1;  // index of the moving piece 
Rectangle mmr;  // rectangle where moving piece is drawn 

// board display variables 
int pieceSize = 60; 
int tileSize = 80;  
int borderWidth = 50; 

private void pictureBox1_Paint(object sender, PaintEventArgs e) 
{ 
    foreach(ChessPiece p in pieces) 
    { 
     if (!p.onBoard) continue; // skip the piece? 

     e.Graphics.DrawImage(imageList1.Images[p.pieceIndex], 
          borderWidth + p.col * tileSize, 
          borderWidth + p.row * tileSize); 

    } 
    // if we have a moving piece.. 
    if (mpIndex >= 0 && !pieces[mpIndex].onBoard) 
     e.Graphics.DrawImage(imageList1.Images[pieces[mpIndex].pieceIndex], 
          mmr.Location); 
} 

Как вы можете видеть, что это на самом деле не очень долго. Он использует несколько очевидных переменных и несколько менее очевидных. Список pieces и ImageList должны быть подготовлены спереди. Прямоугольник mmr устанавливаются в MouseMove:

private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (e.Button == System.Windows.Forms.MouseButtons.Left) 
    { 
     mmr = new Rectangle(e.X - pieceSize/2, 
          e.Y - pieceSize/2, pieceSize, pieceSize); 
     pictureBox1.Invalidate(); // trigger the painting 
    } 
} 

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

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

Если в мероприятии MouseUp мы обнаружили, что движение является незаконным, мы можем просто установить его обратно onBoard, не меняя позицию, и оно будет нарисовано на его старом месте.

В MouseDown мы определяем элемент, на который нажимаем, устанавливаем его onBoard=false и устанавливаем индекс перемещения mpIndex.

Класс для деталей не длинный или сложный;

public class ChessPiece 
{ 
    public bool onBoard { get; set; } // is the piece standing on the board? 
    public int row { get; set; }   // row 
    public int col { get; set; }   // column 
    public char piecetype { get; set; } // a little simplistic..not used.. 
    public char color { get; set;}  // .. could be an enumeration! 
    public int pieceIndex { get; set; } // points into imageList with 12 images 

    public ChessPiece(char color, char type, int r, int c, int ind) 
    { onBoard = true; piecetype = type; this.color = color; 
     row = r; col = c; pieceIndex = ind; } 

} 

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

Вот первые 3 строки кода в создать части:

void makePieces() 
{ 
    ChessPiece 
    p = new ChessPiece('W', 'R', 7, 0, 8); pieces.Add(p); 
    p = new ChessPiece('W', 'N', 7, 1, 10); pieces.Add(p); 
    p = new ChessPiece('W', 'B', 7, 2, 9); pieces.Add(p); 
    .. 

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

enter image description here

+0

Очень приятно, очень похоже на то, что я уже сделал. Моя функция перетаскивания получает положение мыши, а затем непрерывно получает новую позицию. x = x + (новый - старый); старый = новый; на мыши вверх int отменяет фоновый рабочий, а затем корректирует изображение на правый квадрат. Я вижу, как ваш метод будет более выгодным, учитывая, что ему нужно будет задокументировать исходное положение в случае недействительного перемещения. Я получил прозрачность для работы, но она мерцает и имеет проблемы с обновлением достаточно быстро. – GaidenFocus

+0

Вы сейчас перетаскиваете «PictureBox»? Пока неподвижные кусочки не являются «контрольными», перетаскивание может работать, но, как вы видите, действительно нет необходимости иметь какие-либо «элементы управления» вообще. Я использую __only__ 'PictureBox'. Исходная позиция не изменяется до тех пор, пока движение не будет проверено, как я писал в моих комментариях выше. Конечно, он вообще не мерцает. Другие части также PictureBoxes ?? – TaW

+0

Я только что вспомнил после публикации этого вопроса, я храню местоположение в теге. если он недействителен, он найдет исходное местоположение в теге. Да, у меня есть ChessPeice как подкласс PictureBox. Каждый peice - это собственный блок изображения с встроенной системой drag (фоновый метод для нахождения движения мыши и перемещения его соответственно) – GaidenFocus

Смежные вопросы