외부적으로는 같은 기능을 수행하되 내부적으로는 약간 다른 로직을 가진 2개 이상의 Class들을 설계 하기 위해 Abstract Class를 이용하였다.

 

CommonGallery라는 공통의 Abstract Class를 만들었다. CommonGallery는 UserControl과 IContent를 상속 받았다.

 

 

 

    public interface IContent

    {

        event Action ContentTouchDownEvent; 

        void NotifyActivate(bool state);

        void SetWorkDirectory(string workPath);

 

    }

 

IContent.cs

 

 

SetWorkDirectory 메서드는 동일한 동작을 하고 NotifyActivate메서드는 각 Gallery마다 초기화 및 종료가 다르므로 abstract 메서드로 설정하였다. 

 

 

public abstract class CommonGallery : UserControl, IContent

    {

        /// <summary>

        /// Touch 발생하면 호출됩니다.

        /// </summary>

        public event Action ContentTouchDownEvent;

 

        #region Ctor

        public CommonGallery()

        {

            this.PreviewTouchDown += delegate(object sender, System.Windows.Input.TouchEventArgs e)

            {

                if (this.ContentTouchDownEvent != null)

                    this.ContentTouchDownEvent();

            };

            this.PreviewMouseLeftButtonDown += delegate(object sender, System.Windows.Input.MouseButtonEventArgs e)

            {

                if (this.ContentTouchDownEvent != null)

                    this.ContentTouchDownEvent();

            };

        }

        #endregion

 

        /// <summary>

        /// 갤러리에 상황을 알려줍니다.

        /// </summary>

        /// <param name="state"></param>

        public abstract void NotifyActivate(bool state);

/// <summary>

        /// 작업 경로를 설정합니다.

        /// </summary>

        /// <param name="workPath"></param>

        public void SetWorkDirectory(string workPath)

        {

            GalleryManager.Instance.ImageFolderPath = workPath;

        }

    } 

CommonGallery.cs

 

 문자열을 이용한 포토갤러리인 StringPhotoGallery Class에 CommonGallery 상속받은 후 Xaml을 확인할 결과 아래의 메세지가...두둥!

 

"CommonGallery"의 인스턴스를 만들 수 없습니다.

 

 지져분하지만.......CommonGallery Class를 아래와 같이 수정 후 정상적으로 작동하게 되었다.

 

해결방법 1. DEBUG 모드일때에는 abstract 클래스를 class로 임시 변경

 

 

#if DEBUG

    public class CommonGallery : UserControl, IContent

#else

        public abstract class CommonGallery : UserControl, IContent

#endif

 

    {

        /// <summary>

        /// Touch 발생하면 호출됩니다.

        /// </summary>

        public event Action ContentTouchDownEvent;

 

        #region Ctor

#endregion

 

#if DEBUG

        /// <summary>

        /// 갤러리에 상황을 알려줍니다.

        /// </summary>

        /// <param name="state"></param>

        public virtual void NotifyActivate(bool state)

        {

        }

#else

        /// <summary>

        /// 갤러리에 상황을 알려줍니다.

        /// </summary>

        /// <param name="state"></param>

        public abstract void NotifyActivate(bool state);

#endif

        /// <summary>

        /// 작업 경로를 설정합니다.

        /// </summary>

        /// <param name="workPath"></param>

        public void SetWorkDirectory(string workPath)

        {

            GalleryManager.Instance.ImageFolderPath = workPath;

        }

    } 

수정한 CommonGallery.cs

 

abstract Class의 인스턴스를 만들 수 없다면 Debug 모드일때에는 디자인을 확인해야하므로 일반 class와 virtual 메서드를 이용하고, Release 모드일때에는 abstract class로 사용하였다.

 

 정말 지저분하다......ㅠㅠ

 

 

 

해결방법 2. TypeDescriptionProvider 사용

[키즈님 블로그 출처] http://blog.naver.com/kizrael/220475105952

 

테스트 해보니 잘 동작하네요.
단지 abstract class를 상속받는 클래스에 컨트롤을 추가하고 컴파일해도
디자이너에 반영이 안되어서 visual studio를 재시작하면 되네요.

 

되는것 처럼 보이다가......다시 컴파일하면 디자이너 에러 생김...T_T

 

 

[TypeDescriptionProvider(typeof(AbstractControlDescriptionProvider<AbstractControl, UserControl>))]

public abstract class AbstractControl : UserControl

{

 

}

public class AbstractControlDescriptionProvider<TAbstract, TBase> : TypeDescriptionProvider

{

    public AbstractControlDescriptionProvider()

        : base(TypeDescriptor.GetProvider(typeof(TAbstract)))

    {

    }

 

    public override Type GetReflectionType(Type objectType, object instance)

    {

        if (objectType == typeof(TAbstract))

            return typeof(TBase);

 

        return base.GetReflectionType(objectType, instance);

    }

 

    public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)

    {

        if (objectType == typeof(TAbstract))

            objectType = typeof(TBase);

 

        return base.CreateInstance(provider, objectType, argTypes, args);

    }

} 

 

 

 

 

 

 

+ Recent posts