문제

나는 여기 구석으로 물러났습니다.

부모로부터 상속받은 일련의 UserControl이 있습니다. 여기에는 일을 단순화하는 몇 가지 메서드와 이벤트가 포함되어 있어 거의 동일한 코드를 작성할 필요가 없습니다.당신처럼.부모에는 다른 컨트롤이 포함되어 있지 않습니다.

내가 원하는 것은 부모 UserControl에 하나의 이벤트 핸들러를 두는 것입니다. 이 핸들러는 부모 컨트롤만이 할 수 있는 작업을 수행합니다(즉, 부모 컨트롤에 정의된 이벤트에 따라 조건부로 이벤트 호출).그런 다음 이 이벤트 처리기를 자식 컨트롤의 모든 입력 상자에 연결하면 자식 컨트롤이 입력을 구문 분석하고 해당 이벤트를 발생시킬지 여부를 부모 컨트롤에 알리는 작업을 정렬합니다.훌륭하고 깨끗하며 반복적인 복사-붙여넣기 코드가 없습니다. 언제나 버그가 발생합니다).

내 질문은 다음과 같습니다.Visual Studio는 내가 너무 영리하다고 생각하고 "메소드 'checkreadiness'[부모의 이벤트 핸들러]는이 클래스가 이미 메소드를 정의하지 못하기 때문에 이벤트의 방법이 될 수 없다고 경고합니다. 예, Visual Studio, 그게 요점이야.나 원하다 하위 클래스에서 발생하는 이벤트만 처리하는 이벤트 핸들러를 갖고, 그 유일한 작업은 한 줄의 코드를 작성하지 않고도 하위 클래스를 연결할 수 있도록 하는 것입니다.추가 핸들러는 필요하지 않습니다. 필요한 모든 기능은 하위 항목이 사용자 입력을 처리할 때 자연스럽게 호출됩니다.

Visual Studio가 왜 이에 대해 불평하기 시작했는지(이전에도 그랬듯이) 잘 모르겠고, 이를 없애는 방법도 모르겠습니다.가급적이면 CheckReadiness를 호출하는 메서드를 정의하지 않고도 이 작업을 수행하고 싶습니다.이 경고의 원인은 무엇이며, 한 시간 전에도 경고가 발생하는 원인은 무엇이며, 모든 하위 클래스에서 작은 핸들러를 만들지 않고 어떻게 경고를 사라지게 할 수 있습니까?

도움이 되었습니까?

해결책

상위 메소드를 virtual로 선언하고, 하위 클래스에서 이를 대체하고 호출합니다.

base.checkReadyness(sender, e);

(또는 그 파생) 하위 클래스 내에서.이를 통해 상위 이벤트 핸들러를 호출하기 전에 특정 오류 검사 코드를 수행하려는 경우 향후 디자인 발전이 가능해집니다.각 컨트롤에 대해 이와 같이 수백만 개의 이벤트 핸들러를 작성할 필요가 없을 수도 있습니다. 하나만 작성하고 모든 컨트롤을 이 이벤트 핸들러에 연결하면 상위 이벤트 핸들러가 호출됩니다.

제가 주목한 한 가지는 이 모든 코드가 dll 내에 배치되면 dll 내에서 이벤트 핸들러를 호출하려고 할 때 성능 저하가 발생할 수 있다는 것입니다.

다른 팁

저도 방금 이 글을 접했는데, 모든 일을 올바르게 하고 있는 것 같은 느낌이 든다는 데 동의합니다.가상 메소드를 선언하는 것은 해결책이 아니라 기껏해야 해결 방법입니다.

수행 중인 작업은 유효합니다. 즉, 파생 클래스에만 존재하는 컨트롤이고 파생 클래스는 해당 컨트롤의 이벤트 중 하나에 이벤트 핸들러를 연결합니다.이벤트를 처리하는 메서드가 기본 클래스에 정의되어 있다는 점은 여기에도 없고 거기에도 없으며 이벤트에 바인딩하는 시점에서 사용할 수 있습니다.이벤트는 두 번이나 그와 같이 어리석은 것에 연결되지 않으며 단순히 이벤트를 처리하는 메서드가 정의되는 위치의 문제입니다.

가장 확실하게 이것은 가상 메서드가 아닙니다. 파생 클래스가 해당 메서드를 재정의하는 것을 원하지 않습니다.매우 실망스럽고 제 생각에는 dev-studio의 버그입니다.

나 역시 이전 버전의 VS에서는 이벤트 핸들러를 "상속"할 수 있었기 때문에 이 문제를 경험했습니다.따라서 메서드를 재정의하지 않고 제가 찾은 해결책은 단순히 양식의 초기화 단계 어딘가에 이벤트 핸들러를 할당하는 것입니다.내 경우에는 생성자에서 수행했습니다(OnLoad()도 잘 작동할 것이라고 확신합니다).

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

...Ok_Click 처리기가 기본 양식에 있는 위치입니다.생각할 거리.

저는 방금 Merus가 처음 제기한 정확한 문제에 직면했고 응답을 게시한 다른 사람들과 마찬가지로 왜 VS(저는 현재 Visual C# 2010 Express를 사용하고 있습니다) 객체에 이벤트 처리기를 기본에 정의해야 하는지 전혀 명확하지 않습니다. 수업.제가 응답을 게시하는 이유는 기본 클래스 코드를 파생 클래스가 (본질적으로 비어 있는) 이벤트 핸들러에서 간단히 호출하는 보호된 메서드로 만들어 문제를 해결하는 과정에서 기본 클래스의 리팩터링 이름 변경을 수행했기 때문입니다. 클래스 메소드를 실행하고 VS 디자이너가 불평을 멈춘 것을 확인했습니다.즉, 이벤트 핸들러 등록의 이름을 바꾸었고(따라서 더 이상 ControlName_EventName을 사용하여 이벤트 핸들러 이름을 지정하는 VS 디자이너의 규칙을 따르지 않음) 이를 만족시키는 것처럼 보였습니다.그런 다음 적절한 VS 이벤트에 이름을 입력하여 파생 클래스 컨트롤에 대해 (현재 이름이 바뀐) 기본 이벤트 핸들러를 등록하려고 시도했을 때 디자이너는 파생 클래스에 새 이벤트 핸들러를 생성한 다음 삭제하고 파생 클래스 컨트롤은 등록된 상태로 두었습니다. 기본 클래스(이벤트 핸들러) 메서드에.Net에서 예상할 수 있듯이 C#은 우리가 원하는 작업을 합법적으로 찾습니다.디자이너의 이벤트 처리기 명명 규칙을 따를 때 이를 좋아하지 않는 것은 VS 디자이너뿐입니다.디자이너가 그런 식으로 작업할 필요는 없다고 봅니다.누구든지 계속할 시간입니다.

이벤트가 상위 클래스에 이미 정의되어 있는 경우 하위 클래스에서 다시 연결할 필요가 없습니다.그러면 이벤트가 두 번 발생하게 됩니다.

이것이 무슨 일이 일어나고 있는지 확인하십시오.HTH :)

MSDN의 이 문서는 좋은 출발점이 될 것입니다. Visual Basic .NET으로 이벤트 처리기 재정의.다음을 살펴보세요. Handles 절이 파생 클래스에서 문제를 일으킬 수 있는 방법 부분.

부모 클래스에서 메서드를 가상으로 선언한 다음 파생 클래스에서 메서드를 재정의하여 추가 기능을 추가하면 어떨까요?

이벤트 핸들러라는 점을 잊어버리고 하위 클래스에서 적절한 일반 메소드 재정의를 수행하십시오.

다음은 몇 가지 유사해 보이는 형태로 호출되는 기본 메소드를 얻기 위해 수행한 작업입니다. 각 메소드는 일반적인 메소드에 몇 가지 추가 기능을 가지고 있습니다.

        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);
            }

올바른 고정 버튼 이름을 사용하지 않을 가능성은 상속된 핸들러를 수동으로 연결하지 않을 가능성과 동일해 보입니다.

VS Designer에서 코드를 전혀 건너뛰려면 this.DesignMode를 테스트해야 할 수도 있지만 확인하지 않아도 괜찮습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top