728x90
반응형
728x170
▶ DelegateCommand.cs
using System;
using System.Collections.Generic;
using System.Windows.Input;
/// <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
}
728x90
▶ CommandManager.cs
using System;
using System.Collections.Generic;
/// <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
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF/.NETCORE] FaceDetector 클래스 : DetectFacesAsync 메소드를 사용해 얼굴 탐지하기 (0) | 2021.09.23 |
---|---|
[C#/WPF/.NETCORE] 누겟 설치 : Microsoft.Windows.SDK.Contracts (0) | 2021.09.23 |
[C#/WPF/.NETCORE] BitmapImage 클래스 : WINFORM Bitmap 객체에서 비트맵 이미지 구하기 (0) | 2021.09.23 |
[C#/WPF/.NETCORE] IValueConverter 인터페이스 : 비트맵→비트맵 소스 변환자 사용하기 (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] 확장 메뉴 사용하기 (0) | 2021.09.15 |
[C#/WPF] ToggleButton 클래스 : 드롭 다운 버튼/분리 버튼 사용하기 (0) | 2021.09.14 |
댓글을 달아 주세요