Pergunta

Eu meio que me apoiado em um canto aqui.

Eu tenho uma série de UserControls que herdam de um pai, que contém um par de métodos e eventos para simplificar as coisas, então eu não tenho que linhas de escrita e linhas de código quase idêntico. À medida que tu fazes. O pai não contém outros controles.

O que eu quero fazer é apenas ter um manipulador de eventos, no UserControl pai, que vai e faz coisas que só o controle pai pode fazer (ou seja, condicionalmente chamar um evento, como o evento definido no pai). Eu, em seguida, ligar este manipulador de eventos para todas as caixas de meus entrada em meus controles filho, e os controles filho iria resolver a tarefa de analisar a entrada e dizendo o controle pai se deseja lançar esse evento. Agradável e limpo, não repetitivo, copiar e colar código (que para mim sempre resulta em um bug).

Aqui está a minha pergunta. Visual Studio acha que eu estou sendo muito inteligente pela metade, e me avisa que "o método 'CheckReadiness' [o manipulador de eventos no pai] não pode ser o método para um evento porque uma classe esta classe deriva já define o método." Sim, Visual Studio, esse é o ponto . I deseja ter um manipulador de eventos que apenas trata os eventos jogado por classes filhas, e sua única função é permitir-me para ligar as crianças sem ter que escrever uma única linha de código. Eu não preciso desses manipuladores extra -. Tudo a necessidade funcionalidade que é naturalmente chamado como as crianças processar a entrada do usuário

Eu não sei por que Visual Studio tem começaram a reclamar sobre isso agora (como ele me deixa fazer isso antes), e eu não tenho certeza de como fazê-lo ir embora. De preferência, eu gostaria de fazê-lo sem ter que definir um método que apenas chama CheckReadiness. O que está causando este aviso, o que está fazendo com que ele venha agora, quando isso não aconteceu de uma hora atrás, e como eu posso fazer isso ir embora sem recorrer a fazer pequenos manipuladores em todas as classes filhas?

Foi útil?

Solução

Declare o método pai virtual, substituí-lo no classes filhas e chamada

base.checkReadyness(sender, e);

(ou derevation dela) de dentro da classe infantil. Isto permite a evolução futura Design Diga se você quer fazer algum código de verificação de erro específica antes de chamar o manipulador de eventos pai. Você pode não precisar de milhões gravação de manipuladores de eventos como este para cada controle, você pode simplesmente escrever um, ligar todos os controles para este manipulador de eventos que por sua vez chama manipulador de eventos do pai.

Uma coisa que tenho notado é que, se todo este código está sendo colocado dentro de uma dll, então você pode experimentar um desempenho hit tentando chamar um manipulador de eventos de dentro de uma dll.

Outras dicas

Acabei de se deparar com um presente também, concordo que parece que você está fazendo tudo corretamente. Declarando o método virtual é uma forma de contornar na melhor das hipóteses, não uma solução.

O que está sendo feito é válido - um controle que só existe na classe derivada, e a classe derivada é anexar um manipulador de eventos para um dos eventos que do controle. O fato de que o método que está a lidar com o evento é definido na classe base não é nem aqui nem lá, ele está disponível no ponto de ligação para o evento. O evento não está sendo ligado a duas vezes ou qualquer coisa boba como essa, é simplesmente uma questão de onde o método que manipula o evento é definido.

A maioria definitivamente não é um método virtual - Eu não quero que o método a ser substituível por uma classe derivada. Muito frustrante, e na minha opinião, um erro no dev-estúdio.

Eu também tenho tido esse problema porque em versões anteriores do VS, você pode "herdar" os manipuladores de eventos. Assim, a solução que eu encontrei sem ter que substituir métodos é simplesmente atribuir a algum lugar manipulador de eventos na fase de inicialização do formulário. No meu caso, feito no construtor (eu tenho certeza OnLoad () iria funcionar tão bem):

    public MyForm()
    {
        InitializeComponent();
        btnOK.Click += Ok_Click;
    }

... onde reside o manipulador Ok_Click na forma de base. Alimento para o pensamento.

Acabei de correr para o problema exato Merus levantada pela primeira vez e, como outros que postaram respostas, eu não estou de todo claro por que VS (Agora estou usando Visual C # 2010 Express) opõe-se ter o manipulador de eventos definidos na classe base. A razão que eu estou postando uma resposta é que no processo de obtenção em torno do problema, tornando o código de classe base de um método protegido que as classes derivadas simplesmente invocar seus manipuladores (essencialmente vazia) do evento, eu fiz uma renomeação refactor da base método de classe e notou que o designer VS parou de reclamar. Ou seja, ele renomeou o registro de manipulador de eventos (para que ele não seguiu convenção do designer VS de nomear manipuladores de eventos com ControlName_EventName), e que parecia satisfazê-la. Quando eu, em seguida, tentou registrar o manipulador de eventos base (agora renomeada) contra controles derivados classe, digitando o nome no evento VS for o caso, o designer criou um novo manipulador de eventos na classe derivada que eu então apagado, deixando o controle classe derivada registrado para o método da classe base (manipulador de eventos). Net, como seria de esperar, C # encontra o que queremos fazer legítimo. É apenas o designer VS que não gosta quando você seguinte convenção de nomenclatura manipulador de eventos do designer. Eu não vejo a necessidade do designer para trabalhar dessa forma. Anywho, é hora de seguir em frente.

Se o evento já está definido na sua classe pai, você não precisa religar-lo novamente em sua classe criança. Isso fará com que o evento seja acionado duas vezes.

Do verificar se é isso que está acontecendo. HTH:)

Este artigo no MSDN deve ser uma boa pontos de partida: Manipuladores Overriding eventos com Visual Basic .NET . Dê uma olhada no Como a cláusula Handles pode causar problemas na classe derivada seção.

Por que não declarar o método como virtual na classe pai e então você pode substituí-lo nas classes derivadas para adicionar funcionalidade extra?

Esqueça que é um manipulador de eventos e apenas fazer adequada substituição do método regular na classe filha.

Aqui está o que eu fiz para obter métodos base chamados em várias formas de aparência semelhante, cada um deles ter alguns recursos extras para os mais comuns:

        protected override void OnLoad(EventArgs e)
    {
        try
        {
            this.SuspendLayout();
            base.OnLoad(e);

            foreach (Control ctrl in Controls)
            {
                Button btn = ctrl as Button;
                if (btn == null) continue;

                if (string.Equals(btn.Name, "btnAdd", StringComparison.Ordinal))
                    btn.Click += new EventHandler(btnAdd_Click);
                else if (string.Equals(btn.Name, "btnEdit", StringComparison.Ordinal))
                    btn.Click += new EventHandler(btnEdit_Click);
                else if (string.Equals(btn.Name, "btnDelete", StringComparison.Ordinal))
                    btn.Click += new EventHandler(btnDelete_Click);
                else if (string.Equals(btn.Name, "btnPrint", StringComparison.Ordinal))
                    btn.Click += new EventHandler(btnPrint_Click);
                else if (string.Equals(btn.Name, "btnExport", StringComparison.Ordinal))
                    btn.Click += new EventHandler(btnExport_Click);
            }

A chance de uma omissão de usar o nome do botão direito fixo parece o mesmo para mim como a chance de não a fiação do manipulador herdou manualmente.

Note que você pode precisar de teste para this.DesignMode para que você pule o código no VS Designer em tudo, mas ele funciona muito bem para mim, mesmo sem o cheque.

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