我的Windows窗体上有可拖动的图像。 PNG本身具有透明背景,但只有在加载时才会匹配面板的背景颜色。还有其他不同颜色的标签,我希望能够看到,因为我拖了它。任何人都知道如何使用它来实现这一目标?
http://postimg.org/image/d8p4s53pf/
编辑:
尝试使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 :(得分:0)
可拖动的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
图形和电路板图像非常简单。
这是一个屏幕截图,显示了一位白骑士的黑色主教: