[.NET] IExtenderProvider Interface (feat.ToolTip)

2021. 4. 5. 18:21언어/C#. JAVA

반응형

📚 ToolTip 컨트롤

ToolTip 컨트롤은 Form에 ToolTip 컨트롤을 추가했을 때,

다른 컨트롤들에 공통적으로 tooltip1의 ToolTip 이라는 프로퍼티가 생긴다.

 

🔺Form에 ToolTip 컨트롤을 추가했을 때 Button의 속성에 toolTip1의 ToolTip이라는 프로퍼티가 생긴 것을 볼 수 있다.

 

ToolTip 클래스는 Component 클래스 IExtenderProvider 인터페이스를 상속받고 있는데 여기서 프로퍼티 확장을 하기 위한 인터페이스인 IExtenderProvider 인터페이스를 살펴볼 것이다.

 

📖 IExtenderProvider Interface

 - 정의 

   속성을 컨테이너의 다른 구성 요소로 확장하기 위한 인터페이스를 정의한다.

 

 - Method

   bool CanExtend(object target)

 

Method에 대한 설명은 다음과 같이 기재되어 있다. 

bool CanExtend(object) 메서드 하나만 있으며, 이 메서드는 지정된 개체에 대해 확장 속성을 제공 할 수 있는지 여부를 지정한다. 이 개체가 지정된 개체에 Extender 속성을 제공할 수 있으면 true이고, 그렇지 않으면 false입니다.

여기서 지정된 개체IExtenderProvider 를 상속받는 클래스에 ProvideProperty 라는 애트리뷰트를 사용하는데 이때 지정된 Type을 말한다.

 

[ProvideProperty("MyLabel", typeof(Control))] // 지정된 개체는 Control
public class LabelExtender : Control, IExtenderProvider
{
   ...
}

CanExtend() 는 다음과 같이 구현할 수 있다.

bool IExtenderProvider.CanExtend(object target) 
{
    if (target is Control && !(target is ToolTip)) 
    {
    	return true;
    }
    return false;
}

 

📖 IExtenderProvider Interface 상속받아 구현하기

IExtenderProvider를 상속받은 클래스는 반드시 두개의 public 메서드를 구현해야한다.

 

codeproject.com 사이트 글 참고

https://www.codeproject.com/Articles/4683/Getting-to-know-IExtenderProvider

속성을 추가하면 두 개의 공개 메서드를 써야 하며 이러한 메서드는 일반 속성의 가져오기/설정 부분으로 작동하며 Get<Name> 및 Set<Name>이라는 이름이 지정됩니다.

Get<Name> 메서드는 ProviderProperty 속성이 정의하는 유형을 가져와서 속성의 데이터 유형을 반환합니다.

Set<Name> 메서드는 두 개의 인수를 사용합니다. 첫 번째는 Provider Property 속성에 지정된 형식이고, 두 번째는 Get<Name> 반환과 동일한 데이터 형식입니다. 이 값은 사용자가 속성을 설정하고자 하는 값입니다.

Get, Set 메서드를 작성해줘야하는데 여기서 <Name>을 앞서 언급한 ProvideProperty 애트리뷰트의 첫번째 매개변수인 proertyName 과 동일하게 해야한다.

 

아래 소스코드 참고

    [ProvideProperty("MyLabel", typeof(Control))]
    public class LabelExtender : Control, IExtenderProvider
    {
    	//	
        // ...
        //
        
        bool IExtenderProvider.CanExtend(object target)
        {
            if (target is Control && !(target is LabelExtender))
            {
                return true;
            }
            return false;
        }
        
        public string GetMyLabel(Control control)
        {
            string text = (string)hashText[control];
            text = text ?? string.Empty;
            return text;
        }

        public void SetMyLabel(Control control, string value)
        {
            value = value ?? string.Empty;
            if (value.Length == 0)
            {
                hashText.Remove(control);
            }
            else
            {
                hashText[control] = value;
            }
        }
    }

 

 

MSDN의 IExtenderProvider Interface 페이지에 나와있는 예제소스를 그대로 가져와서 동작해봐도 확인이 가능하지만

원리를 이해하면서 직접 구현해보고 싶어서 여러 사이트를 참조해서 확장컨트롤을 구현해봤다.

 

전체 소스

using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace IExtenderProviderDemo
{
    [ProvideProperty("MyLabel", typeof(Control))]
    public class LabelExtender : Control, IExtenderProvider
    {
        private Container components;
        private Hashtable hashText;

        public LabelExtender()
        {
            InitializeComponent();
            hashText = new Hashtable();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.BackColor = System.Drawing.SystemColors.Info;
            this.components = new Container();
            this.ForeColor = System.Drawing.SystemColors.InfoText;
            this.TabStop = false;
        }

        bool IExtenderProvider.CanExtend(object extendee)
        {
            if (extendee is Control &&
                !(extendee is LabelExtender))
            {
                return true;
            }
            return false;
        }
        
        public string GetMyLabel(Control control)
        {
            string text = (string)hashText[control];
            text = text ?? string.Empty;
            return text;
        }

        public void SetMyLabel(Control control, string value)
        {
            value = value ?? string.Empty;
            if (value.Length == 0)
            {
                hashText.Remove(control);
            }
            else
            {
                hashText[control] = value;
            }
        }
    }
}

 

반응형