Управление стеками (Winforms C #) (прозрачный) - PullRequest
0 голосов
/ 08 мая 2009

Меня попросили написать графический интерфейс, который позволит размещать объекты внутри контейнера. Пользователь будет просматривать поля сверху вниз. Они также хотели бы видеть, что уложено внутри. Моей первой мыслью решить эту проблему была прозрачность. Я прочитал некоторые посты о прозрачности, однако не нашел ни одного, который бы решал проблемы прозрачности обоих изображений, чтобы вы могли видеть оба, если они сложены.

Как мне сделать элемент управления прозрачным с другими элементами управления сверху. Если это не реально возможно; Как лучше подойти к этой проблеме?

Я использую пользовательский элемент управления (открытый частичный класс MyControl: Control) для решения проблемы. У меня наконец-то изображение на контроле прозрачное. Все, что нарисовано в родительской форме, показывает через изображение (я использую onPaint для родителя, чтобы нарисовать эллипс и квадрат), однако другие элементы управления, размещенные над ним, больше не прозрачны.

Код, который я использую для этого, приведен ниже:

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);
     }

  } 

Ответы [ 2 ]

1 голос
/ 08 мая 2009

Вы заблокированы в использовании WinForms? Если вам нужно сделать довольно сложные графические вещи (например, как вы описываете) и не можете изменить дизайн своего приложения, вы можете сделать скачок в WPF.

Прошло много времени с тех пор, как я играл в графике GDI +, так что вот идея (но без кода;)):

Ваши стекированные элементы управления действительно должны работать? Если нет, вы можете скопировать их внешний вид в растровые изображения, скрыть их, а затем использовать растровые изображения в своей собственной программе рисования. Когда элемент управления должен работать, вы можете показать его.

Кстати, использовать bitmap.GetPixel или SetPixel очень медленно. Вот какой-то старый код, который я лежал вокруг, который манипулировал 32-битными растровыми изображениями (где синий, зеленый, красный и альфа - байты):

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);
0 голосов
/ 23 сентября 2009

Мне не удалось найти хорошее решение этой проблемы. Единственный способ сделать это - создать собственный элемент управления и использовать много пользовательского кода (который у меня до сих пор не работает полностью). Я собираюсь закрыть эту ветку с ответом:

Слишком сложно ответить на этом форуме.

...