728x90
반응형
728x170
▶ 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
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] ICommand 인터페이스 : 릴레이 명령 사용하기 (0) | 2021.09.23 |
---|---|
[C#/WPF] ICommand 인터페이스 : 매개 변수를 갖는 대리자 명령 사용하기 (0) | 2021.09.23 |
[C#/WPF] ICommand 인터페이스 : 대리자 명령 사용하기 (0) | 2021.09.23 |
[C#/WPF] ComboBox 클래스 : 우선 순위 필터 콤보 박스 사용하기 (0) | 2021.09.17 |
[C#/WPF] 대시보드 애니메이션 사용하기 (0) | 2021.09.16 |
[C#/WPF] ToggleButton 클래스 : 드롭 다운 버튼/분리 버튼 사용하기 (0) | 2021.09.14 |
[C#/WPF] 열거형 정렬하기 (0) | 2021.09.13 |
[C#/WPF] UserControl 엘리먼트 : 로딩 패널 사용하기 (0) | 2021.09.13 |
[C#/WPF] Adorner 클래스 : 슬라이딩 어도너 사용하기 (0) | 2021.09.13 |
[C#/WPF] UserControl 클래스 : 로딩 패널 사용하기 (0) | 2021.09.11 |
댓글을 달아 주세요