첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
0.02MB

▶ Category.cs

using System.Collections.Generic;

namespace TestProject
{
    /// <summary>
    /// 카테고리
    /// </summary>
    public class Category
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 카테고리명 - CategoryName

        /// <summary>
        /// 카테고리명
        /// </summary>
        public string CategoryName { get; set; }

        #endregion
        #region 영화 리스트 - MovieList

        /// <summary>
        /// 영화 리스트
        /// </summary>
        public List<Movie> MovieList { get; set; }

        #endregion
    }
}

 

728x90

 

▶ Movie.cs

namespace TestProject
{
    /// <summary>
    /// Movie class.
    /// </summary>
    public class Movie
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 제목 - Title

        /// <summary>
        /// 제목
        /// </summary>
        public string Title { get; set; }

        #endregion
        #region 링크 - Link

        /// <summary>
        /// 링크
        /// </summary>
        public string Link { get; set; }

        #endregion
        #region 감독 - Director

        /// <summary>
        /// 감독
        /// </summary>
        public string Director { get; set; } 

        #endregion
    }
}

 

300x250

 

▶ DataHelper.cs

using System.Collections.Generic;

namespace TestProject
{
    /// <summary>
    /// 데이터 헬퍼
    /// </summary>
    public class DataHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 카테고리 리스트 구하기 - GetCategoryList()

        /// <summary>
        /// 카테고리 리스트 구하기
        /// </summary>
        /// <returns>카테고리 리스트</returns>
        public static List<Category> GetCategoryList()
        {
            List<Category> list = new List<Category>
            {
                new Category
                {
                    CategoryName = "Action / Sci-Fi",
                    MovieList    = new List<Movie>
                    {
                        new Movie
                        {
                            Title    = "X-Men: First Class",
                            Link     = "http://www.imdb.com/title/tt1270798/",
                            Director = "Matthew Vaughn"
                        },
                        new Movie
                        {
                            Title    = "Rise of the Planet of the Apes",
                            Link     = "http://www.imdb.com/title/tt1318514/",
                            Director = "Rupert Wyatt"
                        },
                        new Movie
                        {
                            Title    = "Iron Man 2",
                            Link     = "http://www.imdb.com/title/tt1228705/",
                            Director = "Jon Favreau"
                        }
                    }
                },
                new Category
                {
                    CategoryName = "Action / Thriller",
                    MovieList    = new List<Movie>
                    {
                        new Movie
                        {
                            Title    = "The Amazing Spider-Man",
                            Link     = "http://www.imdb.com/title/tt0948470/",
                            Director = "Marc Webb"
                        },
                        new Movie
                        {
                            Title    = "The Dark Knight Rises",
                            Link     = "http://www.imdb.com/title/tt1345836/",
                            Director = "Christopher Nolan"
                        },
                        new Movie
                        {
                            Title    = "Captain America: The First Avenger",
                            Link     = "http://www.imdb.com/title/tt0458339/",
                            Director = "Joe Johnston"
                        }
                    }
                },
                new Category
                {
                    CategoryName = "Adventure",
                    MovieList    = new List<Movie>
                    {
                        new Movie
                        {
                            Title    = "Harry Potter and the Deathly Hallows: Part 2",
                            Link     = "http://www.imdb.com/title/tt1201607/",
                            Director = "David Yates"
                        },
                        new Movie
                        {
                            Title    = "The Adventures of Tintin",
                            Link     = "http://www.imdb.com/title/tt0983193/",
                            Director = "Steven Spielberg"
                        },
                        new Movie
                        {
                            Title    = "Transformers: Dark of the Moon",
                            Link     = "http://www.imdb.com/title/tt1399103/",
                            Director = "Michael Bay"
                        },
                        new Movie
                        {
                            Title    = "The Hobbit: An Unexpected Journey",
                            Link     = "http://www.imdb.com/title/tt0903624/",
                            Director = "Peter Jackson"
                        }
                    }
                },
                new Category
                {
                    CategoryName = "Comedy / Romance",
                    MovieList    = new List<Movie>
                    {
                        new Movie
                        {
                            Title    = "Midnight in Paris",
                            Link     = "http://www.imdb.com/title/tt1605783/",
                            Director = "Woody Allen"
                        },
                        new Movie
                        {
                            Title    = "The Hangover",
                            Link     = "http://www.imdb.com/title/tt1119646/",
                            Director = "Todd Phillips"
                        }
                    }
                },
                new Category
                {
                    CategoryName = "Mystery",
                    MovieList    = new List<Movie>
                    {
                        new Movie
                        {
                            Title    = "Source Code",
                            Link     = "http://www.imdb.com/title/tt0945513/",
                            Director = "Duncan Jones"
                        },
                        new Movie
                        {
                            Title    = "Super 8",
                            Link     = "http://www.imdb.com/title/tt1650062/",
                            Director = "J.J. Abrams"
                        },
                        new Movie
                        {
                            Title    = "Black Swan",
                            Link     = "http://www.imdb.com/title/tt0947798/",
                            Director = "Darren Aronofsky"
                        }
                    }
                }
            };

            return list;
        }

        #endregion
    }
}

 

반응형

 

▶ CommandManager.cs

using System;
using System.Collections.Generic;

namespace TestProject
{
    /// <summary>
    /// 명령 관리자
    /// </summary>
    public class CommandManager
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 약한 참조 핸들러 추가하기 - AddWeakReferenceHandler(weakReferenceList, eventHandler)

        /// <summary>
        /// 약한 참조 핸들러 추가하기
        /// </summary>
        /// <param name="weakReferenceList">약한 참조 리스트</param>
        /// <param name="eventHandler">이벤트 핸들러</param>
        public static void AddWeakReferenceHandler(ref List<WeakReference> weakReferenceList, EventHandler eventHandler)
        {
            if(weakReferenceList == null)
            {
                weakReferenceList = new List<WeakReference>();
            }

            weakReferenceList.Add(new WeakReference(eventHandler));
        }

        #endregion
        #region 약한 참조 핸들러 제거하기 - RemoveWeakReferenceHandler(weakReferenceList, eventHandler)

        /// <summary>
        /// 약한 참조 핸들러 제거하기
        /// </summary>
        /// <param name="weakReferenceList">약한 참조 리스트</param>
        /// <param name="eventHandler">이벤트 핸들러</param>
        public static void RemoveWeakReferenceHandler(List<WeakReference> weakReferenceList, EventHandler eventHandler)
        {
            if(weakReferenceList != null)
            {
                for(int i = weakReferenceList.Count - 1; i >= 0; i--)
                {
                    WeakReference weakReference = weakReferenceList[i];

                    EventHandler existingEventHandler  = weakReference.Target as EventHandler;
                   
                    if((existingEventHandler  == null) || (existingEventHandler  == eventHandler))
                    {
                        weakReferenceList.RemoveAt(i);
                    }
                }
            }
        }

        #endregion
        #region 약한 참조 핸들러 호출하기 - CallWeakReferenceHandlers(weakReferenceList)

        /// <summary>
        /// 약한 참조 핸들러 호출하기
        /// </summary>
        /// <param name="weakReferenceList">약한 참조 리스트</param>
        public static void CallWeakReferenceHandlers(List<WeakReference> weakReferenceList)
        {
            if(weakReferenceList != null)
            {
                EventHandler[] eventHandlerArray = new EventHandler[weakReferenceList.Count];

                int count = 0;

                for(int i = weakReferenceList.Count - 1; i >= 0; i--)
                {
                    WeakReference weakReference  = weakReferenceList[i];

                    EventHandler eventHandler = weakReference.Target as EventHandler;
                    
                    if(eventHandler == null)
                    {
                        weakReferenceList.RemoveAt(i);
                    }
                    else
                    {
                        eventHandlerArray[count] = eventHandler;

                        count++;
                    }
                }

                for(int i = 0; i < count; i++)
                {
                    EventHandler eventHandler = eventHandlerArray[i];

                    eventHandler(null, EventArgs.Empty);
                }
            }
        }

        #endregion
    }
}

 

▶ DelegateCommand.cs

using System;
using System.Collections.Generic;
using System.Windows.Input;

namespace TestProject
{
    /// <summary>
    /// 대리자 명령
    /// </summary>
    /// <typeparam name="TParameter">매개 변수 타입</typeparam>
    public class DelegateCommand<TParameter> : ICommand
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Event
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 실행 가능 여부 변경시 이벤트 - CanExecuteChanged

        /// <summary>
        /// 실행 가능 여부 변경시 이벤트
        /// </summary>
        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.AddWeakReferenceHandler(ref this.weakReferenceList, value);
            }
            remove
            {
                CommandManager.RemoveWeakReferenceHandler(this.weakReferenceList, value);
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 실행 액션
        /// </summary>
        private readonly Action<TParameter> executeAction;


        /// <summary>
        /// 실행 가능 여부 함수
        /// </summary>
        private readonly Func<TParameter, bool> canExecuteFunction;

        /// <summary>
        /// 약한 참조 리스트
        /// </summary>
        private List<WeakReference> weakReferenceList;

        #endregion

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

        #region 생성자 - DelegateCommand(executeAction, canExecuteFunction)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="executeAction">실행 액션</param>
        /// <param name="canExecuteFunction">실행 가능 여부 함수</param>
        public DelegateCommand(Action<TParameter> executeAction, Func<TParameter, bool> canExecuteFunction)
        {
            if(executeAction == null)
            {
                throw new ArgumentNullException("executeAction");
            }

            this.executeAction      = executeAction;
            this.canExecuteFunction = canExecuteFunction;
        }

        #endregion
        #region 생성자 - DelegateCommand(executeAction)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="executeAction">실행 액션</param>
        public DelegateCommand(Action<TParameter> executeAction) : this(executeAction, null)
        {
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 실행 가능 여부 구하기 - CanExecute(parameter)

        /// <summary>
        /// 실행 가능 여부 구하기
        /// </summary>
        /// <param name="parameter">매개 변수</param>
        /// <returns>실행 가능 여부</returns>
        public bool CanExecute(TParameter parameter)
        {
            if(this.canExecuteFunction != null)
            {
                return this.canExecuteFunction(parameter);
            }

            return true;
        }

        #endregion
        #region 실행하기 - Execute(parameter)

        /// <summary>
        /// 실행하기
        /// </summary>
        /// <param name="parameter">매개 변수</param>
        public void Execute(TParameter parameter)
        {
            if(this.executeAction != null)
            {
                this.executeAction(parameter);
            }
        }

        #endregion

        #region 실행 가능 여부 구하기 - ICommand.CanExecute(parameter)

        /// <summary>
        /// 실행 가능 여부 구하기
        /// </summary>
        /// <param name="parameter">매개 변수</param>
        /// <returns>실행 가능 여부</returns>
        bool ICommand.CanExecute(object parameter)
        {
            if(parameter == null && typeof(TParameter).IsValueType)
            {
                return this.canExecuteFunction == null;
            }

            return CanExecute((TParameter)parameter);
        }

        #endregion
        #region 실행하기 - ICommand.Execute(parameter)

        /// <summary>
        /// 실행하기
        /// </summary>
        /// <param name="parameter">매개 변수</param>
        void ICommand.Execute(object parameter)
        {
            Execute((TParameter)parameter);
        }

        #endregion

        #region 실행 가능 여부 변경시 이벤트 발생시키기 - RaiseCanExecuteChangedEvent()

        /// <summary>
        /// 실행 가능 여부 변경시 이벤트 발생시키기
        /// </summary>
        public void RaiseCanExecuteChangedEvent()
        {
            FireCanExecuteChangedEvent();
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 실행 가능 여부 변경시 이벤트 발생시키기 - FireCanExecuteChangedEvent()

        /// <summary>
        /// 실행 가능 여부 변경시 이벤트 발생시키기
        /// </summary>
        protected virtual void FireCanExecuteChangedEvent()
        {
            CommandManager.CallWeakReferenceHandlers(this.weakReferenceList);
        }

        #endregion
    }
}

 

▶ MouseCommands.cs

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;

namespace TestProject
{
    /// <summary>
    /// 마우스 명령
    /// </summary>
    public static class MouseCommands
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Class
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 키보드 수정자 체인 - KeyboardModifierChain

        /// <summary>
        /// 키보드 수정자 체인
        /// </summary>
        private class KeyboardModifierChain : ICommand
        {
            //////////////////////////////////////////////////////////////////////////////////////////////////// Import
            ////////////////////////////////////////////////////////////////////////////////////////// Static
            //////////////////////////////////////////////////////////////////////////////// Private

            #region 키보드 상태 구하기 - GetKeyboardState(keyStateByteArray)

            /// <summary>
            /// 키보드 상태 구하기
            /// </summary>
            /// <param name="keyStateByteArray">키 상태 바이트 배열</param>
            /// <returns>처리 결과</returns>
            [return: MarshalAs(UnmanagedType.Bool)]
            [DllImport("user32")]
            private static extern bool GetKeyboardState(byte[] keyStateByteArray);

            #endregion

            //////////////////////////////////////////////////////////////////////////////////////////////////// Event
            ////////////////////////////////////////////////////////////////////////////////////////// Public

            #region 실행 가능 여부 변경시 이벤트 - ICommand.CanExecuteChanged

            /// <summary>
            /// 실행 가능 여부 변경시 이벤트
            /// </summary>
            event EventHandler ICommand.CanExecuteChanged
            {
                add
                {
                }
                remove
                {
                }
            }

            #endregion

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field
            ////////////////////////////////////////////////////////////////////////////////////////// Static
            //////////////////////////////////////////////////////////////////////////////// Private

            #region Field

            /// <summary>
            /// 인스턴스
            /// </summary>
            private static KeyboardModifierChain _instance;

            #endregion

            //////////////////////////////////////////////////////////////////////////////////////////////////// Property
            ////////////////////////////////////////////////////////////////////////////////////////// Static
            //////////////////////////////////////////////////////////////////////////////// Public

            #region 인스턴스 - Instance

            /// <summary>
            /// 인스턴스
            /// </summary>
            public static KeyboardModifierChain Instance
            {
                get
                {
                    return _instance ?? (_instance = new KeyboardModifierChain());
                }
            }

            #endregion

            //////////////////////////////////////////////////////////////////////////////// Private

            #region 수정자 키 - ModifierKeys

            /// <summary>
            /// 수정자 키
            /// </summary>
            private static ModifierKeys ModifierKeys
            {
                get
                {
                    byte[] keyStateByteArray = new byte[0x100];

                    GetKeyboardState(keyStateByteArray);

                    ModifierKeys noneModifierKeys = ModifierKeys.None;

                    if((keyStateByteArray[0x10] & 0x80) == 0x80)
                    {
                        noneModifierKeys |= ModifierKeys.Shift;
                    }

                    if((keyStateByteArray[0x11] & 0x80) == 0x80)
                    {
                        noneModifierKeys |= ModifierKeys.Control;
                    }

                    if((keyStateByteArray[0x12] & 0x80) == 0x80)
                    {
                        noneModifierKeys |= ModifierKeys.Alt;
                    }

                    if(((keyStateByteArray[0x5b] & 0x80) != 0x80) && ((keyStateByteArray[0x5c] & 0x80) != 0x80))
                    {
                        return noneModifierKeys;
                    }

                    return noneModifierKeys | ModifierKeys.Windows;
                }
            }

            #endregion

            //////////////////////////////////////////////////////////////////////////////////////////////////// Method
            ////////////////////////////////////////////////////////////////////////////////////////// Static
            //////////////////////////////////////////////////////////////////////////////// Public

            #region 실행 가능 여부 구하기 - CanExecute(parameter)

            /// <summary>
            /// 실행 가능 여부 구하기
            /// </summary>
            /// <param name="parameter">매개 변수</param>
            /// <returns>실행 가능 여부</returns>
            public bool CanExecute(object parameter)
            {
                return true;
            }

            #endregion
            #region 실행하기 - Execute(parameter)

            /// <summary>
            /// 실행하기
            /// </summary>
            /// <param name="parameter">매개 변수</param>
            public void Execute(object parameter)
            {
                UIElement element = parameter as UIElement;

                if(element != null)
                {
                    ModifierKeys modifierKeys = ModifierKeys;

                    if
                    (
                        ((modifierKeys != ModifierKeys.Control) || !ExecuteCommand(element, GetControlMouseCommand, GetControlMouseCommandParameter)) &&
                        ((modifierKeys != ModifierKeys.Shift  ) || !ExecuteCommand(element, GetShiftMouseCommand  , GetShiftMouseCommandParameter  ))
                    )
                    {
                        ExecuteCommand(element, GetMouseCommand, GetMouseCommandParameter);
                    }
                }
            }

            #endregion

            //////////////////////////////////////////////////////////////////////////////// Private

            #region 명령 실행하기 - ExecuteCommand(element, commandFunction, commandParameterFunction)

            /// <summary>
            /// 명령 실행하기
            /// </summary>
            /// <param name="element">UI 엘리먼트</param>
            /// <param name="commandFunction">명령 함수</param>
            /// <param name="commandParameterFunction">명령 매개 변수 함수</param>
            /// <returns>처리 결과</returns>
            private static bool ExecuteCommand
            (
                UIElement                 element,
                Func<UIElement, ICommand> commandFunction,
                Func<UIElement, object>   commandParameterFunction
            )
            {
                var command = commandFunction(element);

                if(command == null)
                {
                    return false;
                }

                var parameter = commandParameterFunction(element);
                var command2 = command as RoutedCommand;

                if(command2 != null)
                {
                    command2.Execute(parameter, element);
                }
                else
                {
                    command.Execute(parameter);
                }

                return true;
            }

            #endregion
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 마우스 명령 첨부 속성 - MouseCommandProperty

        /// <summary>
        /// 마우스 명령 첨부 속성
        /// </summary>
        public static readonly DependencyProperty MouseCommandProperty = DependencyProperty.RegisterAttached
        (
            "MouseCommand",
            typeof(ICommand),
            typeof(MouseCommands),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(MousePropertyChangedCallback))
        );

        #endregion
        #region 마우스 명령 매개 변수 첨부 속성 - MouseCommandParameterProperty

        /// <summary>
        /// 마우스 명령 매개 변수 첨부 속성
        /// </summary>
        public static readonly DependencyProperty MouseCommandParameterProperty = DependencyProperty.RegisterAttached
        (
            "MouseCommandParameter",
            typeof(object),
            typeof(MouseCommands),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(MousePropertyChangedCallback))
        );

        #endregion
        #region 마우스 명령 액션 첨부 속성 - MouseCommandActionProperty

        /// <summary>
        /// 마우스 명령 액션 첨부 속성
        /// </summary>
        public static readonly DependencyProperty MouseCommandActionProperty = DependencyProperty.RegisterAttached
        (
            "MouseCommandAction",
            typeof(MouseAction),
            typeof(MouseCommands),
            new FrameworkPropertyMetadata(MouseAction.LeftClick, new PropertyChangedCallback(MousePropertyChangedCallback))
        );

        #endregion
        #region CTRL 마우스 명령 첨부 속성 - ControlMouseCommandProperty

        /// <summary>
        /// CTRL 마우스 명령 첨부 속성
        /// </summary>
        public static readonly DependencyProperty ControlMouseCommandProperty = DependencyProperty.RegisterAttached
        (
            "ControlMouseCommand",
            typeof(ICommand),
            typeof(MouseCommands),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(MousePropertyChangedCallback))
        );

        #endregion
        #region CTRL 마우스 명령 매개 변수 첨부 속성 - ControlMouseCommandParameterProperty

        /// <summary>
        /// CTRL 마우스 명령 매개 변수 첨부 속성
        /// </summary>
        public static readonly DependencyProperty ControlMouseCommandParameterProperty = DependencyProperty.RegisterAttached
        (
            "ControlMouseCommandParameter",
            typeof(object),
            typeof(MouseCommands),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(MousePropertyChangedCallback))
        );

        #endregion
        #region SHIFT 마우스 명령 첨부 속성 - ShiftMouseCommandProperty

        /// <summary>
        /// SHIFT 마우스 명령 첨부 속성
        /// </summary>
        public static readonly DependencyProperty ShiftMouseCommandProperty = DependencyProperty.RegisterAttached
        (
            "ShiftMouseCommand",
            typeof(ICommand),
            typeof(MouseCommands),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(MousePropertyChangedCallback))
        );

        #endregion
        #region SHIFT 마우스 명령 매개 변수 첨부 속성 - ShiftMouseCommandParameterProperty

        /// <summary>
        /// SHIFT 마우스 명령 매개 변수 첨부 속성
        /// </summary>
        public static readonly DependencyProperty ShiftMouseCommandParameterProperty = DependencyProperty.RegisterAttached
        (
            "ShiftMouseCommandParameter",
            typeof(object),
            typeof(MouseCommands),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(MousePropertyChangedCallback))
        );

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 마우스 명령 설정하기 - SetMouseCommand(element, value)

        /// <summary>
        /// 마우스 명령 설정하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <param name="value">마우스 명령</param>
        public static void SetMouseCommand(UIElement element, ICommand value)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            element.SetValue(MouseCommandProperty, value);
        }

        #endregion
        #region 마우스 명령 구하기 - GetMouseCommand(element)

        /// <summary>
        /// 마우스 명령 구하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <returns>마우스 명령</returns>
        public static ICommand GetMouseCommand(UIElement element)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            return (ICommand)element.GetValue(MouseCommandProperty);
        }

        #endregion

        #region 마우스 명령 매개 변수 설정하기 - SetMouseCommandParameter(element, value)

        /// <summary>
        /// 마우스 명령 매개 변수 설정하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <param name="value">마우스 명령 매개 변수</param>
        public static void SetMouseCommandParameter(UIElement element, object value)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            element.SetValue(MouseCommandParameterProperty, value);
        }

        #endregion
        #region 마우스 명령 매개 변수 구하기 - GetMouseCommandParameter(element)

        /// <summary>
        /// 마우스 명령 매개 변수 구하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <returns>마우스 명령 매개 변수</returns>
        public static object GetMouseCommandParameter(UIElement element)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            return element.GetValue(MouseCommandParameterProperty);
        }

        #endregion

        #region 마우스 명령 액션 설정하기 - SetMouseCommandAction(element, value)

        /// <summary>
        /// 마우스 명령 액션 설정하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <param name="value">마우스 명령 액션</param>
        public static void SetMouseCommandAction(UIElement element, MouseAction value)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            element.SetValue(MouseCommandActionProperty, value);
        }

        #endregion
        #region 마우스 명령 액션 구하기 - GetMouseCommandAction(element)

        /// <summary>
        /// 마우스 명령 액션 구하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <returns>마우스 명령 액션</returns>
        public static MouseAction GetMouseCommandAction(UIElement element)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            return (MouseAction)element.GetValue(MouseCommandActionProperty);
        }

        #endregion

        #region CTRL 마우스 명령 설정하기 - SetControlMouseCommand(element, value)

        /// <summary>
        /// CTRL 마우스 명령 설정하기
        /// </summary>
        /// <param name="element">엘리먼트</param>
        /// <param name="value">CTRL 마우스 명령</param>
        public static void SetControlMouseCommand(UIElement element, ICommand value)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            element.SetValue(ControlMouseCommandProperty, value);
        }

        #endregion
        #region CTRL 마우스 명령 구하기 - GetControlMouseCommand(element)

        /// <summary>
        /// CTRL 마우스 명령 구하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <returns>CTRL 마우스 명령</returns>
        public static ICommand GetControlMouseCommand(UIElement element)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            return (ICommand)element.GetValue(ControlMouseCommandProperty);
        }

        #endregion

        #region CTRL 마우스 명령 매개 변수 설정하기 - SetControlMouseCommandParameter(element, value)

        /// <summary>
        /// CTRL 마우스 명령 매개 변수 설정하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <param name="value">컨트롤 마우스 명령 매개 변수</param>
        public static void SetControlMouseCommandParameter(UIElement element, object value)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            element.SetValue(ControlMouseCommandParameterProperty, value);
        }

        #endregion
        #region CTRL 마우스 명령 매개 변수 구하기 - GetControlMouseCommandParameter(element)

        /// <summary>
        /// CTRL 마우스 명령 매개 변수 구하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <returns>CTRL 마우스 명령 매개 변수</returns>
        public static object GetControlMouseCommandParameter(UIElement element)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            return element.GetValue(ControlMouseCommandParameterProperty);
        }

        #endregion

        #region SHIFT 마우스 명령 설정하기 - SetShiftMouseCommand(element, value)

        /// <summary>
        /// SHIFT 마우스 명령 설정하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <param name="value">SHIFT 마우스 명령</param>
        public static void SetShiftMouseCommand(UIElement element, object value)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            element.SetValue(ShiftMouseCommandProperty, value);
        }

        #endregion
        #region SHIFT 마우스 명령 구하기 - GetShiftMouseCommand(element)

        /// <summary>
        /// SHIFT 마우스 명령 구하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <returns>SHIFT 마우스 명령</returns>
        public static ICommand GetShiftMouseCommand(UIElement element)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            return (ICommand)element.GetValue(ShiftMouseCommandProperty);
        }

        #endregion

        #region SHIFT 마우스 명령 매개 변수 설정하기 - SetShiftMouseCommandParameter(element, value)

        /// <summary>
        /// SHIFT 마우스 명령 매개 변수 설정하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <param name="value">SHIFT 마우스 명령 매개 변수</param>
        public static void SetShiftMouseCommandParameter(UIElement element, object value)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            element.SetValue(ShiftMouseCommandParameterProperty, value);
        }

        #endregion
        #region SHIFT 마우스 명령 매개 변수 구하기 - GetShiftMouseCommandParameter(element)

        /// <summary>
        /// SHIFT 마우스 명령 매개 변수 구하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <returns>SHIFT 마우스 명령 매개 변수</returns>
        public static object GetShiftMouseCommandParameter(UIElement element)
        {
            if(element == null)
            {
                throw new ArgumentNullException("element");
            }

            return element.GetValue(ShiftMouseCommandParameterProperty);
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private

        #region 마우스 속성 변경시 콜백 처리하기 - MousePropertyChangedCallback(d, e)

        /// <summary>
        /// 마우스 속성 변경시 콜백 처리하기
        /// </summary>
        /// <param name="d">의존 객체</param>
        /// <param name="e">이벤트 인자</param>
        private static void MousePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RefreshMouseBinding((UIElement)d);
        }

        #endregion
        #region 마우스 바인딩 추가하기 - AddMouseBindings(element)

        /// <summary>
        /// 마우스 바인딩 추가하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        private static void AddMouseBindings(UIElement element)
        {
            MouseAction mouseCommandAction = GetMouseCommandAction(element);

            MouseBinding binding1 = new MouseBinding
            {
                Gesture          = new MouseGesture(mouseCommandAction, ModifierKeys.None),
                Command          = KeyboardModifierChain.Instance,
                CommandParameter = element
            };

            MouseBinding binding2 = new MouseBinding
            {
                Gesture          = new MouseGesture(mouseCommandAction, ModifierKeys.Control),
                Command          = KeyboardModifierChain.Instance,
                CommandParameter = element
            };

            MouseBinding binding3 = new MouseBinding
            {
                Gesture          = new MouseGesture(mouseCommandAction, ModifierKeys.Shift),
                Command          = KeyboardModifierChain.Instance,
                CommandParameter = element
            };

            element.InputBindings.Add(binding1);
            element.InputBindings.Add(binding2);
            element.InputBindings.Add(binding3);
        }

        #endregion
        #region 마우스 바인딩 업데이트하기 - UpdateMouseBinding(element, mouseBinding)

        /// <summary>
        /// 마우스 바인딩 업데이트하기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        /// <param name="mouseBinding">마우스 바이닝</param>
        private static void UpdateMouseBinding(UIElement element, MouseBinding mouseBinding)
        {
            MouseGesture gesture = (MouseGesture)mouseBinding.Gesture;

            gesture.MouseAction = GetMouseCommandAction(element);

            mouseBinding.Command          = KeyboardModifierChain.Instance;
            mouseBinding.CommandParameter = element;
        }

        #endregion
        #region 마우스 바인딩 새로 고치기 - RefreshMouseBinding(element)

        /// <summary>
        /// 마우스 바인딩 새로 고치기
        /// </summary>
        /// <param name="element">UI 엘리먼트</param>
        private static void RefreshMouseBinding(UIElement element)
        {
            if(GetMouseCommand(element) != null)
            {
                bool flag = false;

                foreach(object binding in element.InputBindings)
                {
                    MouseBinding mouseBinding = binding as MouseBinding;

                    if(mouseBinding != null)
                    {
                        UpdateMouseBinding(element, mouseBinding);

                        flag = true;
                    }
                }

                if(!flag)
                {
                    AddMouseBindings(element);
                }
            }
        }

        #endregion
    }
}

 

▶ MainWindow.xaml

<Window x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:TestProject" 
    Width="800"
    Height="600"
    Title="확장 메뉴 사용하기"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverterKey" />
        <Style x:Key="CategoryButtonStyleKey" TargetType="{x:Type ToggleButton}">
            <Setter Property="BorderThickness"            Value="0 0 0 1"      />
            <Setter Property="BorderBrush"                Value="#ff232323"    />
            <Setter Property="Padding"                    Value="5 2"          />
            <Setter Property="Background"                 Value="#fff98508"    />
            <Setter Property="Foreground"                 Value="#ffb4b2b2"    />
            <Setter Property="SnapsToDevicePixels"        Value="True"         />
            <Setter Property="HorizontalContentAlignment" Value="Stretch"      />
            <Setter Property="VerticalContentAlignment"   Value="Stretch"      />
            <Setter Property="FontFamily"                 Value="나눔고딕코딩" />
            <Setter Property="FontSize"                   Value="16"           />
            <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ToggleButton">
                    <Border
                        BorderThickness="{TemplateBinding BorderThickness}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        CornerRadius="0"
                        Padding="{TemplateBinding Padding}"
                        Background="{TemplateBinding Background}">
                        <ContentPresenter />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
      <Style.Triggers>
        <Trigger Property="IsChecked" Value="True">
          <Setter Property="Foreground" Value="#FFDCDCDC" />
          <Setter Property="Background" Value="#7F181B1B" />
        </Trigger>
        <Trigger Property="IsChecked" Value="False">
          <Setter Property="Foreground" Value="#FFB4B2B2" />
          <Setter Property="Background" Value="#FFF98508" />
        </Trigger>
        <Trigger Property="IsMouseOver" Value="True">
          <Setter Property="Foreground" Value="#FFB4B2B2" />
          <Setter Property="Background" Value="#7F181B1B" />
        </Trigger>
      </Style.Triggers>
    </Style>
        <Style x:Key="OpenExpanderItemsControlStyleKey" TargetType="{x:Type ItemsControl}">
            <Setter Property="Padding"                    Value="0"            />
            <Setter Property="Background"                 Value="#ffafabab"    />
            <Setter Property="Foreground"                 Value="#ffb4b2b2"    />
            <Setter Property="SnapsToDevicePixels"        Value="True"         />
            <Setter Property="HorizontalContentAlignment" Value="Stretch"      />
            <Setter Property="VerticalContentAlignment"   Value="Stretch"      />
            <Setter Property="FontFamily"                 Value="나눔고딕코딩" />
            <Setter Property="FontSize"                   Value="16"           />
        </Style>
    </Window.Resources>
    <Grid Name="categoryGrid">
        <ScrollViewer VerticalScrollBarVisibility="Auto">
            <ItemsControl ItemsSource="{Binding CategoryList}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <ToggleButton Name="categoryToggleButton"
                                Style="{StaticResource CategoryButtonStyleKey}"
                                Cursor="Hand">
                                <Grid VerticalAlignment="Center">
                                    <TextBlock
                                        Margin="4 2"
                                        Foreground="Black"
                                        FontSize="16"
                                        Text="{Binding CategoryName}" />
                                </Grid>
                            </ToggleButton>
                            <ItemsControl
                                ItemsSource="{Binding MovieList}"
                                Style="{StaticResource OpenExpanderItemsControlStyleKey}"
                                Visibility="{Binding IsChecked,
                                    ElementName=categoryToggleButton,
                                    Converter={StaticResource BooleanToVisibilityConverterKey}}">
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Border
                                            BorderThickness="0">
                                            <Grid>
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition Width="Auto" />
                                                    <ColumnDefinition Width="*"    />
                                                </Grid.ColumnDefinitions>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition Height="4" />
                                                    <RowDefinition            />
                                                    <RowDefinition Height="4" />
                                                    <RowDefinition            />
                                                </Grid.RowDefinitions>
                                                <TextBlock Grid.Row="1" Grid.Column="0"
                                                    Margin="16 0 0 0"
                                                    Foreground="Black"
                                                    Cursor="Hand"
                                                    FontSize="16"
                                                    Text="{Binding Title}"
                                                    local:MouseCommands.MouseCommand="{Binding DataContext.OpenIMDBLinkCommand, ElementName=categoryGrid}"
                                                    local:MouseCommands.MouseCommandParameter="{Binding Link}"
                                                    local:MouseCommands.MouseCommandAction="LeftClick">
                                                    <TextBlock.ToolTip>
                                                        <ToolTip
                                                            Content="{Binding Title}"
                                                            ContentStringFormat="Click here to view {0}." />
                                                    </TextBlock.ToolTip>
                                                </TextBlock>
                                                <TextBlock Grid.Row="1" Grid.Column="1"
                                                    HorizontalAlignment="Right"
                                                    Margin="0 0 8 0"
                                                    Foreground="#ff0083bb"
                                                    FontSize="16"
                                                    Text="{Binding Director}" />
                                                <Path Grid.Row="3" Grid.ColumnSpan="2"
                                                    VerticalAlignment="bottom"
                                                    Height="1"
                                                    Stroke="#7f2f2f2f"
                                                    Stretch="Fill"
                                                    Data="M 0 44.956 L 312.00641 44.956" />
                                            </Grid>
                                        </Border>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
</Window>

 

▶ MainWindow.xaml.cs

using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Input;

namespace TestProject
{
    /// <summary>
    /// 메인 윈도우
    /// </summary>
    public partial class MainWindow
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 카테고리 리스트 - CategoryList

        /// <summary>
        /// 카테고리 리스트
        /// </summary>
        public List<Category> CategoryList { get; set; }

        #endregion
        #region IDMB 링크 열기 명령 - OpenIMDBLinkCommand

        /// <summary>
        /// IDMB 링크 열기 명령
        /// </summary>
        public ICommand OpenIMDBLinkCommand
        {
            get
            {
                return new DelegateCommand<object>(OpenIMDBLink);
            }
        }

        #endregion

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

        #region 생성자 - MainWindow()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();

            DataContext = this;

            CategoryList = DataHelper.GetCategoryList();
        }

        #endregion

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

        #region IDMB 링크 열기 - OpenIMDBLink(instance)

        /// <summary>
        /// IDMB 링크 열기
        /// </summary>
        /// <param name="instance">인스턴스</param>
        private void OpenIMDBLink(object instance)
        {
            string navigateURI = instance as string;

            if(!string.IsNullOrEmpty(navigateURI))
            {
                Process.Start(new ProcessStartInfo(navigateURI));
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요