可拖动的图像

时间:2015-02-23 15:58:53

标签: c# windows-forms-designer

我的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();
    }

1 个答案:

答案 0 :(得分:0)

可拖动的ControlsWinForms中并不难。但是,一旦他们需要透明度,选项就会受到限制:每个选项都必须完全包含在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。矩形mmrMouseMove

中设置
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