2009-10-09 17 views
12

Intenté establecer la opacidad de mi formulario al 50% y luego dibujar una cadena sobre él. Parece que el hilo que dibujé también tiene una opacidad del 50%. ¿Cómo dibujaría una cadena no transparente, pero dejaría que el fondo del formulario se muestre en un 50%?¿Cómo puedo hacer que mi formulario sea transparente, pero no lo que hago?

También estaría dispuesto a hacer esto en WPF si es posible, pero necesitaría instrucciones explícitas o un proyecto de ejemplo ya que nunca antes lo había hecho.

Para aclarar, quiero que el fondo del formulario sea un 80% opaco negro para lo que está debajo, y luego quiero dibujar texto, etc. sobre él y hacer que aparezca 100% opaco.

Respuesta

19

Esto se hace muy fácilmente en WPF:

  1. Conjunto WindowStyle = "Ninguno" en la ventana (nota: esto es necesario, no se puede tener la Transparencia y el estándar de las ventanas de cromo)
  2. Conjunto AllowsTransparency = "True" en la ventana
  3. Establecer un fondo en la ventana usando una brocha con la transparencia, tales como fondo = "# AAFFFFFF"

He aquí una muestra rápida:

<Window 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Height="300" Width="300" AllowsTransparency="True" Background="#AAFFFFFF" WindowStyle="None"> 
<Grid> 
    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" FontWeight="Bold">Hello World!</TextBlock> 
</Grid> 

Ahora, obviamente, ya que se ha desactivado el estándar de cromo Windows, tendrá que proporcionar su propio botón para cerrar/minimizar/maximizar/arrastrar la ventana. Puede hacerlo fácilmente o puede buscar comprar algo como Blendables que viene con un control "Ventana sin cromo" que puede usar.

4
+0

Este no es el mismo, lo que dice es que cuando se dibuja cualquier color que esta clave se establece, se mostrará lo más transparente, lo que significa 0% Opaco (o totalmente transparente dependiendo de si eres un tipo medio lleno). No le permite configurarlo con un 50% de transparencia. – esac

+0

OK. Gracias por la actualización. Tienes razón, por supuesto. TransparencyKey solo funcionará si desea que sea 100% transparente. (Soy un tipo medio lleno). – David

0

en el ControlStyles enumeración MSDN no es un valor llamado SupportsTransparentBackColor. En su forma contructor ejecute esto:

SetStyle(ControlStyles.UserPaint, true); 
SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 
SetStyle(ControlStyles.SupportsTransparentBackColor, true); 

luego puede establecer el color de fondo en Color.Transparente.

Espero que esto ayude.

+0

Hm, esto suena como lo que quiero, sin embargo, estoy recibiendo una caja gris, y parece que cualquier cosa que dibuje en la parte superior si no se muestra. Probé Color.Transparent y this.BackColor = Color.FromArgb (180, 0, 0, 0); – esac

+1

Estoy pensando que esto no funcionará, desde MSDN: si es verdadero, el control acepta un BackColor con un componente alfa de menos de 255 para simular la transparencia. La transparencia se simulará solo si el bit UserPaint se establece en true y el control principal se deriva de Control. Supongo que, dado que el formulario principal no tiene ninguno, falla la última prueba. – esac

+0

Ah, mis disculpas. No me di cuenta de eso. Sospecho que tu teoría es correcta. –

0

Use TransparencyKey para hacer que la ventana sea transparente. Crea un panel vacío con el color de fondo de tu y dale la opacidad deseada.

A continuación, cree todos sus hijos en un contenedor/panel por separado (que a su vez es un hermano del panel translúcido creado anteriormente), y no lo renderice en absoluto.

Esto debería darle el efecto de un fondo translúcido pero controles visibles.

+0

Acabo de probar esto, y obtengo un fondo opaco a través del contenedor transparente, y resulta que es el color al que estoy configurando la TransparencyKey. Por ejemplo, configuré TransparencyKey en rosa, y luego puse un panel de fondo negro opaco al 80%, y lo que veo es un fondo opaco rosado/negro. – esac

+0

Pruebe la configuración de TransparencyKey/form background en Transparent. –

+0

Esto vuelve al mismo problema a continuación. Color.Transparent no es compatible a menos que pueda establecer 'SupportsTransparentBackColor' que no permite a menos que el padre sea un Control. Para el formulario principal, no hay padre: SetStyle (ControlStyles.SupportsTransparentBackColor, true); this.TransparencyKey = Color.Transparent; this.BackColor = Color.Transparent; – esac

0

En WinForms, MSDN dice esto:

La propiedad de opacidad le permite especificar un nivel de transparencia para el formulario y sus controles. Cuando esta propiedad se establece en un valor inferior a 100 por ciento (1.00), toda la forma, incluyendo bordes, se hace más transparente.

Por lo tanto, se cambiará la opacidad de los controles secundarios del formulario en el que establezca la opacidad. Si desea alcanzar diferentes niveles de opacidad en los controles individuales, deberá cambiar a WPF.

0

Supongo que este es un proyecto de WinForms, aunque dijiste que estarías dispuesto a probar WPF.

Lemme cambiar a mi límite de pensamiento lateral: ¿Alguna razón en particular usted no podría simplemente falso? Al igual que en, haga un mapa de bits en PhotoShop Elements o Paint Shop Pro o en alguno que configure como fondo completo del WinForm, y simplemente dibuje el área parcialmente transparente sobre la que se colocarán los controles en ese mapa de bits?

1

Una solución que viene a la mente es usar dos ventanas superpuestas una encima de la otra. Renderice la ventana "inferior" al 50% de opacidad y luego el propietario dibuje su texto en una ventana superpuesta encima de la otra. Si está haciendo pantallas de tipo lable, esto puede ser simple, pero puede complicarse rápidamente si necesita mucha información del usuario que luego podría filtrarse a través de la ventana "principal" o "inferior".

Por lo tanto, tengo que funcionar, pero es un poco ardilla. La solución de dos ventanas parecía prometedora hasta que descubrí que .Net o Win32 hacen alguna crianza auto parental extraña incluso cuando se refieren implícitamente a ella. Probablemente tiene que ver con la forma en que se bombean los mensajes. El padre principal contiene el mensaje de la aplicación pump y el int guess es implícitamente el padre ...

intenté un montón de soluciones provisionales pero esta cosa del temporizador de abajo funcionó mejor. En cualquier caso, podría ser una pista en cuanto a hacerlo mejor ...


// the "main" or transparent window. Notice it just sets and runs the timer 
using System; 
using System.Windows.Forms; 
namespace TransparencyPlusNottransparentTest 
{ 
    public partial class FormMain : Form 
    { 
     public FormMain() 
     { 
      InitializeComponent(); 
     }

private void timer1_Tick(object sender, EventArgs e) 
    { 
     Program.ShowNontransparency(); 
    } 
} 

}

// la ventana transparente "arriba" o no. Observe que el propietario dibuja en // fondo transparente. Los ajustes de tiempo de diseño también están sin borde, etc. usando System.Drawing; usando System.Windows.Forms;

espacio de nombres TransparencyPlusNottransparentTest { FormTop clase parcial pública: Formulario { FormTop pública() { InitializeComponent(); BackColor = Color.Firebrick; TransparencyKey = Color.Firebrick; }

private void FormTop_Paint(object sender, PaintEventArgs e) 
    { 
     e.Graphics.DrawString("Hello Whirrled!", new Font("Tahoma", 14f), Brushes.Black, 10f, 10f); 
    } 
} 

}

// El control de todo este rollo. Crea una instancia de ambas ventanas, // establece la principal como la ventana principal de la aplicación y aloja el // método hacky público para forzar que la ventana no transparente aparezca en la parte superior // y offset para que no oscurezca la parte superior de la ventana principal. usando el sistema; usando System.Drawing; usando System.Windows.Formularios;

espacio de nombres TransparencyPlusNottransparentTest { Programa de clase estática { privada estática FormMain _formMain; private static FormTop _formTop; const int privado XY_OFFSET = 30;

[STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     _formTop = new FormTop(); 
     _formTop.Show(null); 

     _formMain = new FormMain(); 

     Application.Run(_formMain); 
    } 

    public static void ShowNontransparency() 
    { 
     _formTop.Location = 
      new Point(
      _formMain.Location.X + XY_OFFSET, 
      _formMain.Location.Y + XY_OFFSET); 

     _formTop.BringToFront(); 
    } 
} 

}

Cuestiones relacionadas