첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

728x90
반응형

■ PropertyDescriptor 클래스 : 객체 속성 값 변경시 이벤트 처리하기 예제

using System;

Observer<Student> studentObserver = new Observer<Student>();

Student student = new Student() { ID = 100, Name = "홍길동", Grade = 3 };

studentObserver.View = new EntityView<Student>(student);

studentObserver.View["Name"] = "홍길숙"; // 속성에 값을 설정하면 이벤트가 무조건 발생된다.

Console.WriteLine(student.Name);

 

■ PropertyDescriptor 클래스 : 객체 속성 값 변경시 이벤트 처리하기

 

▶ Student.cs

using System;
using System.ComponentModel;

/// <summary>
/// 학생
/// </summary>
public class Student
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Property
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 학번 - ID

    /// <summary>
    /// 학번
    /// </summary>
    public int ID { get; set; }

    #endregion

    #region 성명 - Name

    /// <summary>
    /// 성명
    /// </summary>
    public string Name { get; set; }

    #endregion

    #region 학년 - Grade

    /// <summary>
    /// 학년
    /// </summary>
    public int Grade { get; set; }

    #endregion
}

 

▶ EntityView.cs

/// <summary>
/// 엔터티 뷰
/// </summary>
/// <typeparam name="T">타입</typeparam>
public class EntityView<T> where T : class
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Field
    ////////////////////////////////////////////////////////////////////////////////////////// Private

    #region Field

    /// <summary>
    /// 인스턴스
    /// </summary>
    private T instance;

    /// <summary>
    /// 속성 설명자 컬렉션
    /// </summary>
    private PropertyDescriptorCollection propertyDescriptorCollection;

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Property
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 인덱서 - this[propertyName]

    /// <summary>
    /// 인덱서
    /// </summary>
    /// <param name="propertyName">속성명</param>
    /// <returns>속성 값</returns>
    public object this[string propertyName]
    {
        get
        {
            return GetPropertyValue(propertyName);
        }
        set
        {
            SetPropertyValue(propertyName, value);
        }
    }

    #endregion

    #region 인스턴스 - Instance

    /// <summary>
    /// 인스턴스
    /// </summary>
    public T Instance
    {
        get
        {
            return this.instance;
        }
    }

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - EntityView()

    /// <summary>
    /// 생성자
    /// </summary>
    public EntityView()
    {
        this.instance = Activator.CreateInstance<T>();

        this.propertyDescriptorCollection = TypeDescriptor.GetProperties(this.instance);
    }

    #endregion

    #region 생성자 - EntityView(instance)

    /// <summary>
    /// 생성자
    /// </summary>
    /// <param name="instance">인스턴스</param>
    public EntityView(T instance)
    {
        this.instance = instance;

        this.propertyDescriptorCollection = TypeDescriptor.GetProperties(this.instance);
    }

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Method
    ////////////////////////////////////////////////////////////////////////////////////////// Private

    #region 속성 값 설정하기 - SetPropertyValue(propertyName, value)

    /// <summary>
    /// 속성 값 설정하기
    /// </summary>
    /// <param name="propertyName">속성명</param>
    /// <param name="value">값</param>
    private void SetPropertyValue(string propertyName, object value)
    {
        this.propertyDescriptorCollection[propertyName].SetValue(this.instance, value);
    }

    #endregion

    #region 속성 값 구하기 - GetPropertyValue(proeprtyName)

    /// <summary>
    /// 속성 값 구하기
    /// </summary>
    /// <param name="propertyName">속성명</param>
    /// <returns>속성 값</returns>
    private object GetPropertyValue(string propertyName)
    {
        return this.propertyDescriptorCollection[propertyName].GetValue(this.instance);
    }

    #endregion
}

 

▶ Observer.cs

/// <summary>
/// 관찰자
/// </summary>
public class Observer<T> where T : class
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Field
    ////////////////////////////////////////////////////////////////////////////////////////// Private

    #region Field

    /// <summary>
    /// 엔터티 뷰
    /// </summary>
    private EntityView<T> entityView;

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Property
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 뷰 - View

    /// <summary>
    /// 뷰
    /// </summary>
    public EntityView<T> View
    {
        get
        {
            return this.entityView;
        }
        set
        {
            if(value != null && this.entityView != value)
            {
                if(this.entityView != null)
                {
                    foreach(PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(this.entityView.Instance))
                    {
                        propertyDescriptor.RemoveValueChanged(this.entityView.Instance, new EventHandler(OnPropertyChanged));
                    }
                }

                this.entityView = value;

                foreach(PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(this.entityView.Instance))
                {
                    propertyDescriptor.AddValueChanged(this.entityView.Instance, new EventHandler(OnPropertyChanged));
                }
            }
        }
    }

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 생성자 - Observer()

    /// <summary>
    /// 생성자
    /// </summary>
    public Observer()
    {
    }

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Method
    ////////////////////////////////////////////////////////////////////////////////////////// Private

    #region 속성 변경시 처리하기 - OnPropertyChanged(sender, e)

    /// <summary>
    /// 속성 변경시 처리하기
    /// </summary>
    /// <param name="sender">이벤트 발생자</param>
    /// <param name="e">이벤트 인자</param>
    private void OnPropertyChanged(object sender, EventArgs e)
    {
        Console.WriteLine(sender.ToString());
    }

    #endregion
}
728x90
반응형
Posted by 사용자 icodebroker

댓글을 달아 주세요