none
Panel "elevado" RRS feed

  • Pergunta

  • Bom dia pessoal,

    Coloquei um Panel no meu form, e setei a propriedade BorderStyle como Fixed3D.
    O painel fica com aparência de "Baixo Relevo", gostaria que ele ficasse "elevado". Alguém sabe como fazer isso?

    Esses conceitos de "Baixo Relevo" e "elevado" são opções que o Visio oferece. Utilizei ele para desenhar as telas.
    Por isso, gostaria de manter o layout proposto no protótipo.

    Muito obrigado,
    Ewerton.
    quarta-feira, 8 de julho de 2009 12:17

Respostas

  • Olá Ewerton,

    O controle Panel do .NET não permite esse tipo de borda "elevada" de forma nativa, então você tem que optar por outra alternativa, como por exemplo:

    Mais fácil:
    - Simular um Panel "elevado" com um controle do tipo Button, sem o texto (Text = string.Empty), e desabilitado (Enabled = false). É a alternativa mais simples, em minha opinião, e vai causar o mesmo efeito visual para quem utiliza a aplicação.


    Médio:
    - Utilizar um painel sem borda (BorderStyle = none), e no evento Paint desse painel, desenhar uma linha branca no canto esquerdo superior, e outra preta no canto esquerdo inferior, para causar o efeito "elevado". Algo mais ou menos assim:

    private void seuPainel_Paint(object sender, PaintEventArgs e)
    {
        // Obtém a área do painel
        Rectangle areaPainel = seuPainel.ClientRectangle;
    
        // Canto superior esquerdo
        Point p1 = new Point(areaPainel.Left, areaPainel.Top); 
    
        // Canto superior direito
        Point p2 = new Point(areaPainel.Right-1, areaPainel.Top);
    
        // Canto inferior esquerdo
        Point p3 = new Point(areaPainel.Left, areaPainel.Bottom-1);
    
        // Canto inferior direito
        Point p4 = new Point(areaPainel.Right - 1, areaPainel.Bottom - 1);
        
        // Desenha as linhas brancas e as linhas pretas no painel
        Pen penBranca = new Pen(System.Drawing.Color.White);
        Pen penPreta = new Pen(System.Drawing.Color.Black);
    
        Graphics g = seuPainel.CreateGraphics();
        g.DrawLine(penBranca, p1, p2);
        g.DrawLine(penBranca, p1, p3);
        g.DrawLine(penPreta, p2, p4);
        g.DrawLine(penPreta, p3, p4);
    }
    


    Mais difícil:
    - Utilizar as APIs da User32.dll para alterar a aparência do controle:

    private void SeuFormulario_Load(object sender, EventArgs e)
    {
        // Valores utilizados para definir 
        // as características do controle
        const int GWL_EXSTYLE = -20;
        const int WS_EX_DLGMODALFRAME = 0x00000001;
        const int SWP_NOSIZE = 0x0001;
        const int SWP_NOMOVE = 0x0002;
        const int SWP_NOZORDER = 0x0004;
        const int SWP_NOACTIVATE = 0x0010;
        const int SWP_FRAMECHANGED = 0x0020;
    
        // Obtém o handle do painel
        IntPtr hWnd = this.seuPainel.Handle;
        
        // Obtém os estilos atuais do painel
        int style = GetWindowLong(hWnd, GWL_EXSTYLE);
        
        // Modifica a aparência do controle para ter esse formato "elevado"
        SetWindowLong(hWnd, GWL_EXSTYLE, (style | WS_EX_DLGMODALFRAME));
        SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, (SWP_FRAMECHANGED | SWP_NOSIZE | 
            SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE));            
    }
    
    // Referência para as APIs da User32
    [DllImport("user32.dll")]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    
    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    
    [DllImport("user32.dll")]
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
    


    Vale lembrar que o atributo DllImport está no namespace System.Runtime.InteropServices.

    Abraços,
    Caio Proiete



    Caio Proiete Siga-me no Twitter!
    http://www.caioproiete.com
    quinta-feira, 9 de julho de 2009 00:56
    Moderador
  • Ah... eu não podia passar por aqui e não citar o WPF...


    Mas me mantendo ao WinForms, não acho q é o que vc quer exatamente mas um visual legal e facil de se arrumar e colocando uma panel preto sobre um panel branco do mesmo tamanho... porem com o branco um pouco mais para cima e para o lado que o preto....


    Se não funciona de um jeito, tente de outro totalmente diferente ^_^
    • Marcado como Resposta Ewerton Rubio quarta-feira, 22 de julho de 2009 12:02
    quinta-feira, 9 de julho de 2009 02:46
    Moderador

Todas as Respostas

  • Olá Ewerton,

    O controle Panel do .NET não permite esse tipo de borda "elevada" de forma nativa, então você tem que optar por outra alternativa, como por exemplo:

    Mais fácil:
    - Simular um Panel "elevado" com um controle do tipo Button, sem o texto (Text = string.Empty), e desabilitado (Enabled = false). É a alternativa mais simples, em minha opinião, e vai causar o mesmo efeito visual para quem utiliza a aplicação.


    Médio:
    - Utilizar um painel sem borda (BorderStyle = none), e no evento Paint desse painel, desenhar uma linha branca no canto esquerdo superior, e outra preta no canto esquerdo inferior, para causar o efeito "elevado". Algo mais ou menos assim:

    private void seuPainel_Paint(object sender, PaintEventArgs e)
    {
        // Obtém a área do painel
        Rectangle areaPainel = seuPainel.ClientRectangle;
    
        // Canto superior esquerdo
        Point p1 = new Point(areaPainel.Left, areaPainel.Top); 
    
        // Canto superior direito
        Point p2 = new Point(areaPainel.Right-1, areaPainel.Top);
    
        // Canto inferior esquerdo
        Point p3 = new Point(areaPainel.Left, areaPainel.Bottom-1);
    
        // Canto inferior direito
        Point p4 = new Point(areaPainel.Right - 1, areaPainel.Bottom - 1);
        
        // Desenha as linhas brancas e as linhas pretas no painel
        Pen penBranca = new Pen(System.Drawing.Color.White);
        Pen penPreta = new Pen(System.Drawing.Color.Black);
    
        Graphics g = seuPainel.CreateGraphics();
        g.DrawLine(penBranca, p1, p2);
        g.DrawLine(penBranca, p1, p3);
        g.DrawLine(penPreta, p2, p4);
        g.DrawLine(penPreta, p3, p4);
    }
    


    Mais difícil:
    - Utilizar as APIs da User32.dll para alterar a aparência do controle:

    private void SeuFormulario_Load(object sender, EventArgs e)
    {
        // Valores utilizados para definir 
        // as características do controle
        const int GWL_EXSTYLE = -20;
        const int WS_EX_DLGMODALFRAME = 0x00000001;
        const int SWP_NOSIZE = 0x0001;
        const int SWP_NOMOVE = 0x0002;
        const int SWP_NOZORDER = 0x0004;
        const int SWP_NOACTIVATE = 0x0010;
        const int SWP_FRAMECHANGED = 0x0020;
    
        // Obtém o handle do painel
        IntPtr hWnd = this.seuPainel.Handle;
        
        // Obtém os estilos atuais do painel
        int style = GetWindowLong(hWnd, GWL_EXSTYLE);
        
        // Modifica a aparência do controle para ter esse formato "elevado"
        SetWindowLong(hWnd, GWL_EXSTYLE, (style | WS_EX_DLGMODALFRAME));
        SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, (SWP_FRAMECHANGED | SWP_NOSIZE | 
            SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE));            
    }
    
    // Referência para as APIs da User32
    [DllImport("user32.dll")]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    
    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    
    [DllImport("user32.dll")]
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
    


    Vale lembrar que o atributo DllImport está no namespace System.Runtime.InteropServices.

    Abraços,
    Caio Proiete



    Caio Proiete Siga-me no Twitter!
    http://www.caioproiete.com
    quinta-feira, 9 de julho de 2009 00:56
    Moderador
  • Ah... eu não podia passar por aqui e não citar o WPF...


    Mas me mantendo ao WinForms, não acho q é o que vc quer exatamente mas um visual legal e facil de se arrumar e colocando uma panel preto sobre um panel branco do mesmo tamanho... porem com o branco um pouco mais para cima e para o lado que o preto....


    Se não funciona de um jeito, tente de outro totalmente diferente ^_^
    • Marcado como Resposta Ewerton Rubio quarta-feira, 22 de julho de 2009 12:02
    quinta-feira, 9 de julho de 2009 02:46
    Moderador
  • Olá pessoal,

    Acabei mexendo em outras coisas do projeto e acabei deixando momentaneamente de lado a questão do panel, mas muito obrigado pelas sugestões!
    Vou tentar fazer!

    Abraços,
    Ewerton.
    quarta-feira, 22 de julho de 2009 12:03