简体   繁体   English

堆叠控件(Winforms C#)(透明)

[英]Stacking Controls (Winforms C#) (Transparent)

I have been asked to write a GUI that will allow objects to be stacked inside a container. 我被要求编写一个GUI,该GUI将允许将对象堆叠在容器内。 The user will be viewing the boxes from a top down view point. 用户将从上至下的角度查看这些框。 They also would like to be able to see what is stacked inside. 他们还希望能够看到里面堆积的东西。 My first thought to solve this was transparency. 解决这个问题的第一个想法是透明度。 I have read some of the posts on transparency, however I didn't find any that solved the issues of both images being transparent so you was able to see both if they are stacked. 我已经阅读了一些有关透明度的文章,但是我找不到能解决两个图像都透明的问题,因此您可以看到两个图像是否堆叠在一起。

How can I get the control to be transparent with other controls on top. 如何使控件与顶部的其他控件透明。 If this isn't really possible; 如果这不可能的话; What is a better aproach to this problem? 有什么更好的方法来解决这个问题?

I am using a custom control (public partial class MyControl : Control) to solve the issue. 我正在使用自定义控件(公共局部类MyControl:Control)来解决此问题。 I finally have the image on the control transparent. 我终于在控件上透明了图像。 Anything that is drawn on the parent form shows thru the image (I'm using the onPaint for the parent to paint an elipse and a square), however other controls placed over it is no longer transparent. 在父窗体上绘制的所有内容都可以显示图像(我正在使用onPaint为父窗体绘制椭圆和正方形),但是放置在它上面的其他控件不再透明。

The code I'm using to accomplish this is below: 我用来实现此目的的代码如下:

public Image Image 
  {
     get { return m_Image; }
     set { m_Image = value; }
  }
private void GridControl_Paint(object sender, PaintEventArgs e)
  {
     if (Image != null)
     {

        Graphics g = e.Graphics;
        Bitmap bitMap = new Bitmap(Image);

        //This is not working... the color array always comes back empty
        //This is how I would rather making things transparent...
        Color[] colorArray = bitMap.Palette.Entries;

        if (colorArray.Length > 0)
        {

           ColorMap[] colorMap = new ColorMap[colorArray.Length];

           for (int index = 0; index < colorArray.Length; index++)
           {
              colorMap[index] = new ColorMap();
              colorMap[index].OldColor = colorArray[index];
              colorMap[index].NewColor = Color.Transparent;
           }

        }

        //Ok fine so the above is not working... let me force it.
        //Get each pixel in the image and change the color.
        else
        {
           for (int x = 0; x < bitMap.Width; x++)
           {
              for (int y = 0; y < bitMap.Height; y++)
              {
                 Color pixelColor = bitMap.GetPixel(x, y);
                 Color newColor = Color.FromArgb(100, pixelColor);

                 bitMap.SetPixel(x, y, newColor);
              }
           }
        }

        bitMap.MakeTransparent();

        g.DrawImage(bitMap, this.ClientRectangle);
     }

  } 

Are you locked into using WinForms? 您是否被锁定使用WinForms? If you need to do much moderately tricky graphics stuff (such as you describe) and can't redesign your app to get around it, you could make the leap into WPF. 如果您需要做一些中等难度的图形工作(例如您所描述的),并且无法重新设计应用程序以解决问题,则可以迈入WPF。

It's been a while since I've played in GDI+ graphics, so here's an idea (but no code ;) ): 自从我玩过GDI +图形以来已经有一段时间了,所以这是一个主意(但没有代码;)):

Do your stacked controls actually need to work? 您堆叠的控件实际上需要工作吗? If not, you can copy their appearance to bitmaps, hide them, then use the bitmaps in your own paint routine. 如果不是,则可以将其外观复制到位图,将其隐藏,然后在自己的绘制例程中使用位图。 When a control needs to work you can unhide it. 当控件需要工作时,您可以取消隐藏它。

By the way, using bitmap.GetPixel or SetPixel is very slow. 顺便说一句,使用bitmap.GetPixel或SetPixel非常慢。 Here's some old code I had lying around that manipulated 32bit bitmaps (where blue, green, red and alpha are bytes): 这是一些我操纵过的32位位图的旧代码(蓝色,绿色,红色和alpha是字节):

BitmapData bmpData = bitmap.LockBits(pixelRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

unsafe
{
    byte* bytes = (byte*)bmpData.Scan0;
    for (int row = 0; row < pixelRect.Height; row++)
    {
        for (int col = 0; col < pixelRect.Width * 4; ) // * 4: 4 bytes per pixel 
        {
            bytes[row * bmpData.Stride + col++] = blue;
            bytes[row * bmpData.Stride + col++] = green;
            bytes[row * bmpData.Stride + col++] = red;
            bytes[row * bmpData.Stride + col++] = alpha;
        }
    }
}

// Unlock the bits.
bitmap.UnlockBits(bmpData);

I have not been able to find a good solution to this problem. 我无法找到解决此问题的好方法。 The only way I have found to do this is thru creating a custom control and using a lot of custom code (that I still don't have working fully). 我发现做到这一点的唯一方法是通过创建自定义控件并使用大量自定义代码(我仍然无法充分工作)。 I am going to close this thread with the answer being: 我将关闭该线程,答案是:

It is too complicated to answer in this forum. 在此论坛中回答太复杂了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM