Pergunta

Ambiente:. .NET Framework 2.0, o VS 2008

Eu estou tentando criar uma subclasse de certos controles .net (rótulo, painel) que passarão através de determinados eventos de mouse (MouseDown, MouseMove, MouseUp) para o controle pai (ou, em alternativa ao formulário de nível superior). Eu posso fazer isso criando manipuladores para esses eventos em instâncias dos controles padrão, p.ex.:.

public class TheForm : Form
{
    private Label theLabel;

    private void InitializeComponent()
    {
        theLabel = new Label();
        theLabel.MouseDown += new MouseEventHandler(theLabel_MouseDown);
    }

    private void theLabel_MouseDown(object sender, MouseEventArgs e)
    {
        int xTrans = e.X + this.Location.X;
        int yTrans = e.Y + this.Location.Y;
        MouseEventArgs eTrans = new MouseEventArgs(e.Button, e.Clicks, xTrans, yTrans, e.Delta);
        this.OnMouseDown(eTrans);
    }
}

Eu não posso mover o manipulador de eventos em uma subclasse do controle, porque os métodos que aumentam os eventos no controle pai estão protegidos e não tenho um qualificador para o controle pai:

Não é possível acesso protegido System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs) membro através de um qualificador do tipo System.Windows.Forms.Control; o qualificador deve ser do tipo TheProject.NoCaptureLabel (ou derivado dele).

Eu estou olhando para substituir o método WndProc do controle no meu sub-classe, mas espero que alguém pode me dar uma solução mais limpa.

Foi útil?

Solução

Sim. Depois de muita pesquisa, descobri o artigo "Controls Flutuante, dica de estilo" , que usa WndProc para alterar a mensagem de WM_NCHITTEST para HTTRANSPARENT, tornando o Control transparente para eventos do mouse.

Para conseguir isso, criar um controle herdado de Label e simplesmente adicione o seguinte código.

protected override void WndProc(ref Message m)
{
    const int WM_NCHITTEST = 0x0084;
    const int HTTRANSPARENT = (-1);

    if (m.Msg == WM_NCHITTEST)
    {
        m.Result = (IntPtr)HTTRANSPARENT;
    }
    else
    {
        base.WndProc(ref m);
    }
}

Eu testei isso no Visual Studio 2010 com o .NET Framework 4 Client Profile.

Outras dicas

Você precisa escrever um método público / protegido em sua classe base que irá aumentar o evento para você. Em seguida, chamar esse método de classe derivada.

ou

É isso que você quer?

public class MyLabel : Label
{
    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        //Do derived class stuff here
    }
}

O WS_EX_TRANSPARENT estendido estilo da janela realmente faz isso (é o que in-place dicas usar). Você pode querer considerar a aplicação deste estilo, em vez de codificação de lotes de manipuladores de fazê-lo para você.

Para fazer isso, substituir o método CreateParams:

protected override CreateParams CreateParams
{
  get
  {
    CreateParams cp=base.CreateParams;
    cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT
    return cp;
  }
}

Para ler mais:

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top