문제

RichTextBox뿐만 아니라 텍스트 상자에 대한 이벤트 핸들러가 있습니다. 코드는 동일하지만

핸들러 #1에서 나는한다 :

RichTextBox tb = (RichTextBox)sender

그에 따라 처리기 #2에서 :

TextBox tb = (TextBox)sender

그렇게하면 전송 컨트롤을 완전히 조작 할 수 있습니다. 내가 알고 싶은 것은 전송 객체를 TextBox 또는 RichTextBox에 사용하여 사용하는 방법에 따라 텍스트 상자 또는 RichTextBox를 어떻게 캐스팅 할 수 있습니까?

sender.GetType().Name

그런 다음 런타임에 컨트롤을 만들고 작업하십시오. 이렇게하면 하나의 이벤트 처리기 기능 만 필요합니다. 코드가 적고 오류가 적고 유지 관리가 쉬워지고 건조 할 수 있습니다. :-)

도움이 되었습니까?

해결책

필요한 속성에 따라 텍스트 상자와 RichTextBox 모두로서 텍스트 박스베이스로 발신자를 해당 하위 클래스에서 상속받을 수 있습니다.

다른 팁

당신은 캐스팅 할 필요가 없습니다. 나는 시작했을 때 같은 방식으로 생각했지만,이 '패턴'은 잘못되었으며 실제로 논리적이지 않습니다.

가장 좋은 방법은 다음과 같은 것을 사용하는 것입니다.

if (sender is TextBox)
{
  TextBox tb = (TextBox)sender;
}
else if (sender is RichTextBox)
{
  RichTextBox rtb = (RichTextBox)sender;
}
else
{
  // etc
}

나는 이것이 매우 오래된 게시물이라는 것을 알고 있지만 프레임 워크 4에서는 발신자를 컨트롤로 캐스팅 할 수 있습니다.

Control cntrl = (Control)sender;
cntrl.Text = "This is a " + sender.GetType().ToString();

참고 모든 다른 컨트롤이 공통적으로 가지고있는 컨트롤 만 참조 할 수 있습니다 (예 : 텍스트).

RichTextBox textbox = sender as RichTextBox;
if (textbox != null)
{
   // do stuff as a rtb
   textbox.Text = "I'm a rtb";
   return;
}

TextBox textbox = sender as TextBox;
if (textbox != null)
{
   // do stuff as a textbox
   textbox.Text = "I'm a textbox";
}

캐스팅은 컴파일 타임에만 수행 할 수 있으므로 컴파일 타임에 캐스트하려는 유형을 알아야합니다. 따라서 캐스팅시 런타임 유형 (gettype ()에 의해 반환)를 사용할 수 없습니다.

그것이 다형성이라면 당신이 찾고있는 반사를 통해 이름 속성에 액세스 할 수 있습니다. 이벤트 핸들러를 재사용 할 수는 있지만 그렇게하지 않을 것입니다.

강력한 타이핑을 원한다면 두 발신자의 공통 기본 클래스 또는 인터페이스가 유일한 방법입니다.

사용할 수있는 유형 이름보다는 '~이다'.

유형을 알고 싶고 객체 참조가 필요하지 않은 경우 :

if (sender is RichTextBox)
{
    // ...
}
else if (sender is TextBox)
{
    // ...
}

그러나 일반적으로 객체를 원합니다. C#7은 멋진 구문을 가지고있어 값을 인라인으로 테스트하고 얻을 수 있습니다.

if (sender is RichTextBox richTextBox)
{
    richTextBox.Text = "I am rich";
}
else if (sender is TextBox textBox)
{
    textBox.Text = "I am not rich";
}

인라인-임시 변수를 사용하여 캐스트를 처리 할 수도 있습니다.

if (sender is RichTextBox tb)
{
    // ... //
} 
else if (sender is TextBox tb)
{
    // ... //
}

코드가 동일하다면 관리해야합니까? 캐스팅이 있는지 궁금합니다 Control 필요한 모든 것을주지 않을 것입니다 ...

하나의 복잡한 핸들러가 여러 간단한 핸들러보다 반드시 더 나은 것은 아닙니다. 어느 쪽이든, 당신은 가지다 이 경로로 이동하려면 "AS"/"는 바람직합니다 (문자열 등에 의존하지 않음).

TextBox tb = sender as TextBox;
if(tb!=null) {/* TextBox specific code */}
...

코드를 반복하지 않으려면 두 컨트롤을 모두 시전하고 공통 조치를 텍스트 박스베이스를 인수로 취하는 별도의 메소드로 리팩토링 할 수 있습니다. 이벤트에서 처리기는 컨트롤을 System.Windows.Forms.TextBoxBase로 변환하여 두 컨트롤이 TexBboxBase에서 파생되어 메소드를 호출합니다.

이러한 컨트롤의 특정 속성이 필요한 경우이 리팩토링은 작동하지 않습니다.

위 코드의 일반 버전 :

public static void CastAndUse<T>(object item, Action<T> action) where T : class
{
    T thing = item as T;

    if (thing != null)
    {
        action(thing);
    }
}

사용 :

CastAndUse(sender, new Action((foo) => foo = bar));

완벽하지는 않지만 편리합니다.

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