Pergunta

Pediram-me para escrever um GUI que permitirá que objetos para ser empilhados dentro de um recipiente. O usuário estará vendo as caixas de uma parte superior para baixo ponto de vista. Eles também gostaria de ser capaz de ver o que está empilhada dentro. Meu primeiro pensamento para resolver este foi a transparência. Eu li alguns dos posts sobre a transparência, no entanto I não encontrou qualquer que resolveu as questões de ambas as imagens ser transparente para que você foi capaz de ver ambos se eles estão empilhados.

Como posso obter o controle para ser transparente com outros controles na parte superior. Se isso não é realmente possível; O que é uma melhor aproach para este problema?

Eu estou usando um controle personalizado (público classe MyControl parcial: Control) para resolver a questão. Eu finalmente ter a imagem no controle transparente. Tudo o que é desenhado no formulário pai mostra através da imagem (estou usando o OnPaint para o pai a pintar uma elipse e um quadrado), no entanto outros controles colocados sobre ele não é mais transparente.

O código que estou usando para alcançar este objetivo é abaixo:

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

  } 
Foi útil?

Solução 2

Eu não tenho sido capaz de encontrar uma boa solução para este problema. A única maneira que eu encontrei para fazer isso é através de criar um controle personalizado e usando um monte de código personalizado (que eu ainda não têm totalmente funcional). Vou fechar esta discussão com o ser resposta:

É muito complicado responder neste fórum.

Outras dicas

Você está bloqueado em usar WinForms? Se você precisar de fazer muito moderadamente complicado coisas gráficos (como você descreve) e não pode redesenhar seu aplicativo para contornar o problema, você pode fazer o salto para WPF.

Tem sido um tempo desde que eu joguei no GDI + gráficos, então aqui está uma idéia (mas nenhum código;)):

fazer seus controles empilhados realmente precisa trabalhar? Se não, você pode copiar sua aparência para bitmaps, escondê-los, em seguida, usar os bitmaps em sua própria rotina de pintura. Quando um controle necessidades para trabalhar, você pode mostrá-lo.

A propósito, usando bitmap.GetPixel ou SetPixel é muito lento. Aqui está algum código antigo que eu tinha em torno de mentir que bitmaps de 32 bits manipulado (onde o azul, verde, vermelho e alfa são bytes):

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);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top