2011-05-24 24 views
7

Tengo un formulario que tiene algunos controles en sí mismo (btnCreateReport, pnlDarkLayer) .Tengo un panel que se ajusta para formar (Dock = Fill) y está en la parte posterior de todos los controles. Cuando el usuario hace clic en el botón btnCreateReport, llamo al método pnlDarkLayer BringToFront y después de algunos cálculos llamo al método SendToBack() del botón. Quiero dibujar una capa oscura en los controles de formulario y desactivar todos los controles en el formulario. ¿Es posible? Gracias.WinForm Control with Opacity

Tal vez este código u ayuda a entender mi propósito:

private void btnCreateReport_Click(object sender, EventArgs e) 
{ 
    pnlDarkLayer.BackColor = Color.FromArgb(100, Color.Gray);   

    pnlDarkLayer.BringToFront(); 
    btnCreateReport.Enabled = false; 

    Thread ProcessReport = new Thread(new ThreadStart(ProcessingReport)); 
    ProcessReport.Start(); 
    while (ProcessReport.IsAlive) 
    { 
     Application.DoEvents(); 
    } 
    pnlDarkLayer.SendToBack(); 

    btnCreateReport.Enabled = true; 

} 

Este código ocultar todos los controles, pero yo no quiero ocultar los controles de la form.I quieren dibujar una capa oscura sobre ellos. Y el usuario debe poder ver los controles. Necesito algo así como la propiedad de opacidad de los formularios para sus controles.

tengo prueba de esto:

pnlDarkLayer.CreateGraphics().CompositingMode=System.Drawing.Drawing2D.CompositingMode.SourceOver;

actualización: Tengo prueba de éste: (utilizar un formulario en lugar de Panel)

private void btnCreateReport_Click(object sender, EventArgs e) 
{   

    btnCreateReport.Enabled = false; 

    frmProgress ProgressForm = new frmProgress(); 
    ProgressForm.TopLevel = false; 
    ProgressForm.Parent = this; 
    ProgressForm.BringToFront(); 
    this.Controls.Add(ProgressForm); 
    ProgressForm.Show(); 

    Thread ProcessReport = new Thread(new ThreadStart(ProcessingReport)); 
    ProcessReport.Start(); 

    while (ProcessReport.IsAlive) 
    { 
     Application.DoEvents(); 
    } 
    ProgressForm.Close(); 
    btnCreateReport.Enabled = true; 

} 

pero no puedo ver el ProgressForm en mi forma.

+3

Aparte de todo lo que tenga que ver con la opacidad, * por favor * no utilice ese tipo de bucle llamando a 'DoEvents'. O bien, dale a 'ProcessingReport' algún tipo de gancho para usar para llamar a algún código cuando está terminado, o simplemente coloca el último bit de código al final del método 'ProcessingReport', recordando usar' BeginInvoke' para asegurarte de que se ejecuta en el Hilo de interfaz de usuario. Debería evitar 'Application.DoEvents' en casi todos los casos. –

+0

Entonces, ¿cómo puedo hacer algo después de que el hilo terminó su trabajo? – Saleh

+0

para deshabilitar todos los controles, también puede intentar hacer esto: foreach (elemento de Control en Controles) {item.Enabled = false;} – Reniuz

Respuesta

6

De http://support.microsoft.com/kb/943454

controles transparentes en Windows Forms son transparente en relación con sus padres, no a otros controles. Transparencia en WinForms es más parecido al camuflaje que la transparencia verdadera. Un control transparente no le permite ver el control detrás de él a través del formulario . Le pide a su padre que dibuje su propio fondo en el control "transparente" . Esta es la razón por la cual un control transparente muestra la forma detrás de él, pero cubre cualquier otro control.

Para poner en práctica la transparencia en relación con otros controles requiere hacer lo mismo cosa, pero en una escala más grande: en lugar de sólo pedir a los padres a recurrir a fondo del control de primer plano, el control tiene que pedir a todos los controles detrás para dibujar en su fondo. Esto solo funcionará para los controles que proporcionan algún método para solicitar que se dibujen y no se actualizarán automáticamente cuando cambie la imagen del control de fondo .

La página también proporciona un ejemplo de código (en vb, por desgracia) para mostrar cómo se hace esto.

5

Si entiendo correctamente, quiere 'oscurecer' el contenido del formulario mientras se está ejecutando una operación.

Como alguien ha dicho antes aquí, es muy complicado hacer lo correcto. Pero hay una manera de hacerlo fácilmente, con una reserva (ver más abajo).

Look en este código fuente:

public partial class Form1 : Form 
{ 
    private Bitmap _background; 
    private bool _isShrouded; 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     if (true == _isShrouded && null!=_background) 
      e.Graphics.DrawImage(_background, 0, 0); 
    } 

    public void Shroud() 
    { 
     if (false == _isShrouded) 
     { 
      CreateScreenshot(); 

      HideControls(); 

      _isShrouded = true; 

      this.Invalidate(); 
     } 
    } 

    public void Unshroud() 
    { 
     if (true == _isShrouded) 
     { 
      ShowControls(); 

      _isShrouded = false; 

      this.Invalidate(); 
     } 


    } 

    private void HideControls() 
    { 
     foreach (Control control in this.Controls) 
      control.Visible = false; 
    } 

    private void ShowControls() 
    { 
     foreach (Control control in this.Controls) 
      control.Visible = true; 
    } 

    private void CreateScreenshot() 
    { 
     Rectangle area = this.RectangleToScreen(this.ClientRectangle); 
     Bitmap screenGrab = new Bitmap(area.Width, area.Height); 

     Brush dark = new SolidBrush(Color.FromArgb(128, Color.Black)); 

     Graphics g = Graphics.FromImage(screenGrab); 
     g.CopyFromScreen(area.Location, Point.Empty, area.Size); 
     g.FillRectangle(dark, 0, 0, area.Width, area.Height); 
     g.Dispose(); 

     _background = screenGrab; 
    } 
} 

La clase Form1 tiene dos métodos principales, la cubierta() y Unshroud().

El método Shroud() toma una instantánea del formulario y lo copia en un mapa de bits, que luego se "oscurece". Los controles están ocultos y el mapa de bits está pintado en el formulario.

El método UnShroud() restaura los controles y le dice a la forma que ya no dibuje el mapa de bits.

Requiere dos variables privadas: una para almacenar el mapa de bits, y una bandera que mantiene el estado actual.

También reemplaza a OnPaint() porque necesita dibujar la imagen de fondo cuando está 'oculta'.

Nota: El recubrimiento funciona al tomar una captura de pantalla del formulario. Esto significa que la forma DEBE SER la forma más alta en el punto de envolvimiento. Si el formulario está oscurecido por otros formularios, se incluirán en la captura de pantalla. Espero que esto no sea un problema para ti.

Nota: Como dije antes, la única manera de lograr la transparencia en Windows es la cooperación total de todos los controles involucrados, y esa es una tarea ardua. Cualquier otra cosa (incluida esta solución) es realmente un engaño.