728x90
반응형
728x170
■ Adorner 클래스를 사용해 슬라이딩 어도너를 만드는 방법을 보여준다.
▶ UIElementAdorner.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
namespace TestProject
{
/// <summary>
/// UI 엘리먼트 어도너
/// </summary>
public class UIElementAdorner : Adorner
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 자식 엘리먼트
/// </summary>
private readonly UIElement childElement;
/// <summary>
/// 왼쪽 오프셋
/// </summary>
private double leftOffset;
/// <summary>
/// 위쪽 오프셋
/// </summary>
private double topOffset;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 왼쪽 오프셋 - LeftOffset
/// <summary>
/// 왼쪽 오프셋
/// </summary>
public double LeftOffset
{
get
{
return this.leftOffset;
}
set
{
this.leftOffset = value;
UpdateLocation();
}
}
#endregion
#region 위쪽 오프셋 - TopOffset
/// <summary>
/// 위쪽 오프셋
/// </summary>
public double TopOffset
{
get
{
return this.topOffset;
}
set
{
this.topOffset = value;
UpdateLocation();
}
}
#endregion
#region 논리적 자식 열거자 - LogicalChildren
/// <summary>
/// 논리적 자식 열거자
/// </summary>
protected override IEnumerator LogicalChildren
{
get
{
List<UIElement> list = new List<UIElement> { this.childElement };
return list.GetEnumerator();
}
}
#endregion
#region 비주얼 자식 수 - VisualChildrenCount
/// <summary>
/// 비주얼 자식 수
/// </summary>
protected override int VisualChildrenCount
{
get { return 1; }
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - UIElementAdorner(adornedElement, childElement)
/// <summary>
/// 생성자
/// </summary>
/// <param name="adornedElement">장식 엘리먼트</param>
/// <param name="childElement">자식 엘리먼트</param>
public UIElementAdorner(UIElement adornedElement, UIElement childElement) : base(adornedElement)
{
if(childElement == null)
{
throw new ArgumentNullException("childElement");
}
this.childElement = childElement;
AddLogicalChild(childElement);
AddVisualChild(childElement);
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 희망 변환 구하기 - GetDesiredTransform(transform)
/// <summary>
/// 희망 변환 구하기
/// </summary>
/// <param name="transform">변환</param>
/// <returns>희망 변환</returns>
public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
{
GeneralTransformGroup transformGroup = new GeneralTransformGroup();
transformGroup.Children.Add(base.GetDesiredTransform(transform));
transformGroup.Children.Add(new TranslateTransform(this.leftOffset, this.topOffset));
return transformGroup;
}
#endregion
#region 오프셋 설정하기 - SetOffset(leftOffset, topOffset)
/// <summary>
/// 오프셋 설정하기
/// </summary>
/// <param name="leftOffset">왼쪽 오프셋</param>
/// <param name="topOffset">위쪽 오프셋</param>
public void SetOffset(double leftOffset, double topOffset)
{
this.leftOffset = leftOffset;
this.topOffset = topOffset;
UpdateLocation();
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 측정하기 (오버라이드) - MeasureOverride(availableSize)
/// <summary>
/// 측정하기 (오버라이드)
/// </summary>
/// <param name="availableSize">희망 크기</param>
/// <returns>크기</returns>
protected override Size MeasureOverride(Size availableSize)
{
this.childElement.Measure(availableSize);
return this.childElement.DesiredSize;
}
#endregion
#region 배열하기 (오버라이드) - ArrangeOverride(finalSize)
/// <summary>
/// 배열하기 (오버라이드)
/// </summary>
/// <param name="finalSize">최종 크기</param>
/// <returns>크기</returns>
protected override Size ArrangeOverride(Size finalSize)
{
this.childElement.Arrange(new Rect(finalSize));
return finalSize;
}
#endregion
#region 비주얼 자식 구하기 - GetVisualChild(index)
/// <summary>
/// 비주얼 자식 구하기
/// </summary>
/// <param name="index">인덱스</param>
/// <returns>비주얼 자식</returns>
protected override Visual GetVisualChild(int index)
{
return this.childElement;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 위치 업데이트하기 - UpdateLocation()
/// <summary>
/// 위치 업데이트하기
/// </summary>
private void UpdateLocation()
{
AdornerLayer adornerLayer = Parent as AdornerLayer;
if(adornerLayer != null)
{
adornerLayer.Update(AdornedElement);
}
}
#endregion
}
}
▶ SlidingElement.cs
using System.Windows.Controls;
namespace TestProject
{
/// <summary>
/// 슬라이딩 엘리먼트
/// </summary>
public class SlidingElement : Control
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - SlidingElement(dataContext)
/// <summary>
/// 생성자
/// </summary>
/// <param name="dataContext">데이터 컨텍스트</param>
public SlidingElement(object dataContext)
{
DataContext = dataContext;
}
#endregion
}
}
▶ SlidingAdorner.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace TestProject
{
/// <summary>
/// 슬라이딩 어도너
/// </summary>
public class SlidingAdorner : Control
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration
////////////////////////////////////////////////////////////////////////////////////////// Public
#region SlidingAdornerSlideDirection
/// <summary>
/// 슬라이딩 어도너 슬라이드 방향
/// </summary>
public enum SlidingAdornerSlideDirection
{
/// <summary>
/// 오른쪽
/// </summary>
Right,
/// <summary>
/// 왼쪽
/// </summary>
Left,
/// <summary>
/// 위쪽
/// </summary>
Up,
/// <summary>
/// 아래쪽
/// </summary>
Down
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 슬라이드 방향 속성 - SlideDirectionProperty
/// <summary>
/// 슬라이드 방향 속성
/// </summary>
public static readonly DependencyProperty SlideDirectionProperty = DependencyProperty.Register
(
"SlideDirection",
typeof(SlidingAdornerSlideDirection),
typeof(SlidingAdorner),
new UIPropertyMetadata(SlidingAdornerSlideDirection.Right)
);
#endregion
#region 슬라이드 거리 속성 - SlideDistanceProperty
/// <summary>
/// 슬라이드 거리 속성
/// </summary>
public static readonly DependencyProperty SlideDistanceProperty = DependencyProperty.Register
(
"SlideDistance",
typeof(double),
typeof(SlidingAdorner),
new UIPropertyMetadata(100.0)
);
#endregion
#region 슬라이드 지속 시간 속성 - SlideDurationProperty
/// <summary>
/// 슬라이드 지속 시간 속성
/// </summary>
public static readonly DependencyProperty SlideDurationProperty = DependencyProperty.Register
(
"SlideDuration",
typeof(int),
typeof(SlidingAdorner),
new UIPropertyMetadata(500)
);
#endregion
#region 슬라이드 엘리먼트 오프셋 속성 - SlideElementOffsetProperty
/// <summary>
/// 슬라이드 엘리먼트 오프셋 속성
/// </summary>
public static readonly DependencyProperty SlideElementOffsetProperty = DependencyProperty.Register
(
"SlideElementOffset",
typeof(double),
typeof(SlidingAdorner),
new UIPropertyMetadata(0.0)
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// UI 엘리먼트 어도너
/// </summary>
private UIElementAdorner uiElementAdorner;
/// <summary>
/// 슬라이딩 엘리먼트
/// </summary>
private SlidingElement slidingElement;
/// <summary>
/// 슬라이딩 엘리먼트 표시 여부
/// </summary>
private bool isSlidingElementVisible;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 슬라이드 방향 - SlideDirection
/// <summary>
/// 슬라이드 방향
/// </summary>
public SlidingAdornerSlideDirection SlideDirection
{
get
{
return (SlidingAdornerSlideDirection)GetValue(SlideDirectionProperty);
}
set
{
SetValue(SlideDirectionProperty, value);
}
}
#endregion
#region 슬라이드 거리 - SlideDistance
/// <summary>
/// 슬라이드 거리
/// </summary>
public double SlideDistance
{
get
{
return (double)GetValue(SlideDistanceProperty);
}
set
{
SetValue(SlideDistanceProperty, value);
}
}
#endregion
#region 슬라이드 지속 시간 - SlideDuration
/// <summary>
/// 슬라이드 지속 시간
/// </summary>
public int SlideDuration
{
get
{
return (int)GetValue(SlideDurationProperty);
}
set
{
SetValue(SlideDurationProperty, value);
}
}
#endregion
#region 슬라이드 엘리먼트 오프셋 - SlideElementOffset
/// <summary>
/// 슬라이드 엘리먼트 오프셋
/// </summary>
public double SlideElementOffset
{
get
{
return (double)GetValue(SlideElementOffsetProperty);
}
set
{
SetValue(SlideElementOffsetProperty, value);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - SlidingAdorner()
/// <summary>
/// 생성자
/// </summary>
public SlidingAdorner()
{
MouseEnter += Control_MouseEnter;
MouseLeave += Control_MouseLeave;
}
#endregion
#region 생성자 - SlidingAdorner(dataContext)
/// <summary>
/// 생성자
/// </summary>
/// <param name="dataContext">데이터 컨텍스트</param>
public SlidingAdorner(object dataContext)
{
DataContext = dataContext;
MouseEnter += Control_MouseEnter;
MouseLeave += Control_MouseLeave;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 변환 그룹 구하기 - GetTransformGroup(scaleX, scaleY, x, y)
/// <summary>
/// 변환 그룹 구하기
/// </summary>
/// <param name="scaleX">스케일 X</param>
/// <param name="scaleY">스케일 Y</param>
/// <param name="x">X</param>
/// <param name="y">Y</param>
/// <returns>변환 그룹</returns>
private static TransformGroup GetTransformGroup(double scaleX, double scaleY, int x, int y)
{
TransformGroup transformGroup = new TransformGroup();
ScaleTransform scaleTransform = new ScaleTransform { ScaleX = scaleX, ScaleY = scaleY };
transformGroup.Children.Add(scaleTransform);
TranslateTransform translateTransform = new TranslateTransform { X = x, Y = y };
transformGroup.Children.Add(translateTransform);
return transformGroup;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Public
#region 템플리트 적용시 처리하기 - OnApplyTemplate()
/// <summary>
/// 템플리트 적용시 처리하기
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.slidingElement = new SlidingElement(DataContext);
this.slidingElement.MouseLeave += slidingElement_MouseLeave;
this.slidingElement.RenderTransform = GetTransformGroup(1, 1, 1, 1);
switch(SlideDirection)
{
case SlidingAdornerSlideDirection.Right :
case SlidingAdornerSlideDirection.Left :
this.slidingElement.Width = SlideDistance;
break;
case SlidingAdornerSlideDirection.Down :
case SlidingAdornerSlideDirection.Up :
this.slidingElement.Height = SlideDistance;
break;
}
this.uiElementAdorner = new UIElementAdorner(this, this.slidingElement);
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Private
////////////////////////////////////////////////////////////////////// Event
#region 컨트롤 마우스 진입시 처리하기 - Control_MouseEnter(sender, e)
/// <summary>
/// 컨트롤 마우스 진입시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Control_MouseEnter(object sender, MouseEventArgs e)
{
if(!this.isSlidingElementVisible)
{
ShowSlidingAdorner();
}
}
#endregion
#region 컨트롤 마우스 이탈시 처리하기 - Control_MouseLeave(sender, e)
/// <summary>
/// 컨트롤 마우스 이탈시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Control_MouseLeave(object sender, MouseEventArgs e)
{
ProcessMouseLeave();
}
#endregion
#region 슬라이딩 엘리먼트 마우스 이탈시 처리하기 - slidingElement_MouseLeave(sender, e)
/// <summary>
/// 슬라이딩 엘리먼트 마우스 이탈시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void slidingElement_MouseLeave(object sender, MouseEventArgs e)
{
ProcessMouseLeave();
}
#endregion
////////////////////////////////////////////////////////////////////// Function
#region 슬라이딩 어도너 표시하기 - ShowSlidingAdorner()
/// <summary>
/// 슬라이딩 어도너 표시하기
/// </summary>
private void ShowSlidingAdorner()
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
if(adornerLayer == null)
{
return;
}
switch(SlideDirection)
{
case SlidingAdornerSlideDirection.Left :
this.uiElementAdorner.SetOffset(-SlideElementOffset, 0);
break;
case SlidingAdornerSlideDirection.Right :
this.uiElementAdorner.SetOffset(ActualWidth + SlideElementOffset, 0);
break;
case SlidingAdornerSlideDirection.Down :
this.uiElementAdorner.SetOffset(0, ActualHeight + SlideElementOffset);
break;
case SlidingAdornerSlideDirection.Up :
this.uiElementAdorner.SetOffset(0, -SlideElementOffset);
break;
}
adornerLayer.Add(this.uiElementAdorner);
AnimateScaleTransform();
AnimateTranslateTransform();
AnimateOpacity();
}
#endregion
#region 스케일 변환 애니메이션 적용하기 - AnimateScaleTransform()
/// <summary>
/// 스케일 변환 애니메이션 적용하기
/// </summary>
private void AnimateScaleTransform()
{
SplineDoubleKeyFrame splineDoubleKeyFrame1 = new SplineDoubleKeyFrame
{
KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0)),
Value = 0
};
SplineDoubleKeyFrame splineDoubleKeyFrame2 = new SplineDoubleKeyFrame
{
KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(SlideDuration)),
Value = 1
};
DoubleAnimationUsingKeyFrames doubleAnimationUsingKeyFrames = new DoubleAnimationUsingKeyFrames();
doubleAnimationUsingKeyFrames.KeyFrames.Add(splineDoubleKeyFrame1);
doubleAnimationUsingKeyFrames.KeyFrames.Add(splineDoubleKeyFrame2);
ScaleTransform scaleTransform = ((TransformGroup)this.slidingElement.RenderTransform).Children[0] as ScaleTransform;
if(scaleTransform != null)
{
switch(SlideDirection)
{
case SlidingAdornerSlideDirection.Right :
case SlidingAdornerSlideDirection.Left :
scaleTransform.BeginAnimation(ScaleTransform.ScaleXProperty, doubleAnimationUsingKeyFrames);
break;
case SlidingAdornerSlideDirection.Down :
case SlidingAdornerSlideDirection.Up :
scaleTransform.BeginAnimation(ScaleTransform.ScaleYProperty, doubleAnimationUsingKeyFrames);
break;
}
}
}
#endregion
#region 이동 변환 애니메이션 적용하기 - AnimateTranslateTransform()
/// <summary>
/// 이동 변환 애니메이션 적용하기
/// </summary>
private void AnimateTranslateTransform()
{
SplineDoubleKeyFrame splineDoubleKeyFrame1 = new SplineDoubleKeyFrame
{
KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0)),
Value = 0
};
SplineDoubleKeyFrame splineDoubleKeyFrame2 = new SplineDoubleKeyFrame
{
KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(SlideDuration))
};
switch(SlideDirection)
{
case SlidingAdornerSlideDirection.Right :
case SlidingAdornerSlideDirection.Down :
splineDoubleKeyFrame2.Value = 0;
break;
case SlidingAdornerSlideDirection.Left :
case SlidingAdornerSlideDirection.Up :
splineDoubleKeyFrame2.Value = -SlideDistance;
break;
}
DoubleAnimationUsingKeyFrames doubleAnimationUsingKeyFrames = new DoubleAnimationUsingKeyFrames();
doubleAnimationUsingKeyFrames.KeyFrames.Add(splineDoubleKeyFrame1);
doubleAnimationUsingKeyFrames.KeyFrames.Add(splineDoubleKeyFrame2);
TranslateTransform translateTransform = ((TransformGroup)this.slidingElement.RenderTransform).Children[1] as TranslateTransform;
if(translateTransform != null)
{
switch(SlideDirection)
{
case SlidingAdornerSlideDirection.Right :
case SlidingAdornerSlideDirection.Left :
translateTransform.BeginAnimation(TranslateTransform.XProperty, doubleAnimationUsingKeyFrames);
break;
case SlidingAdornerSlideDirection.Down :
case SlidingAdornerSlideDirection.Up :
translateTransform.BeginAnimation(TranslateTransform.YProperty, doubleAnimationUsingKeyFrames);
break;
}
}
}
#endregion
#region 불투명도 애니메이션 적용하기 - AnimateOpacity()
/// <summary>
/// 불투명도 애니메이션 적용하기
/// </summary>
private void AnimateOpacity()
{
DoubleAnimation doubleAnimation = new DoubleAnimation
{
Duration = new Duration(TimeSpan.FromMilliseconds(SlideDuration)),
From = 0,
To = 1
};
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(doubleAnimation);
Storyboard.SetTarget(doubleAnimation, this.slidingElement);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(UIElement.Opacity)"));
storyboard.Begin();
}
#endregion
#region 슬라이딩 어도너 숨기기 - HideSlidingAdorner()
/// <summary>
/// 슬라이딩 어도너 숨기기
/// </summary>
private void HideSlidingAdorner()
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
if(adornerLayer != null)
{
adornerLayer.Remove(this.uiElementAdorner);
}
}
#endregion
#region 마우스 이탈시 처리하기 - ProcessMouseLeave()
/// <summary>
/// 마우스 이탈시 처리하기
/// </summary>
private void ProcessMouseLeave()
{
if(!IsMouseOver && !this.slidingElement.IsMouseOver)
{
HideSlidingAdorner();
this.isSlidingElementVisible = false;
}
else
{
this.isSlidingElementVisible = true;
}
}
#endregion
}
}
▶ DragCanvas.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Media3D;
namespace TestProject
{
/// <summary>
/// 드래그 캔버스
/// </summary>
public class DragCanvas : Canvas
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 드래그 가능 여부 첨부 속성 - CanBeDraggedProperty
/// <summary>
/// 드래그 가능 여부 첨부 속성
/// </summary>
public static readonly DependencyProperty CanBeDraggedProperty = DependencyProperty.RegisterAttached
(
"CanBeDragged",
typeof(bool),
typeof(DragCanvas),
new UIPropertyMetadata(true)
);
#endregion
#region 드래그 허용 여부 속성 - AllowDraggingProperty
/// <summary>
/// 드래그 허용 여부 속성
/// </summary>
public static readonly DependencyProperty AllowDraggingProperty = DependencyProperty.Register
(
"AllowDragging",
typeof(bool),
typeof(DragCanvas),
new PropertyMetadata(true)
);
#endregion
#region 뷰 외부 드래그 허용 여부 속성 - AllowDragOutOfViewProperty
/// <summary>
/// 뷰 외부 드래그 허용 여부 속성
/// </summary>
public static readonly DependencyProperty AllowDragOutOfViewProperty = DependencyProperty.Register
(
"AllowDragOutOfView",
typeof(bool),
typeof(DragCanvas),
new UIPropertyMetadata(false)
);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 드래그 엘리먼트
/// </summary>
private UIElement dragElement;
/// <summary>
/// 드래그 시작 포인트
/// </summary>
private Point dragStartPoint;
/// <summary>
/// 드래그 시작 오프셋 X
/// </summary>
private double dragStartOffsetX;
/// <summary>
/// 드래그 시작 오프셋 Y
/// </summary>
private double dragStartOffsetY;
/// <summary>
/// 수정 오프셋 X
/// </summary>
private bool modifyOffsetX;
/// <summary>
/// 수정 오프셋 Y
/// </summary>
private bool modifyOffsetY;
/// <summary>
/// 드래그 여부
/// </summary>
private bool isDragging;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 드래그 허용 여부 - AllowDragging
/// <summary>
/// 드래그 허용 여부
/// </summary>
public bool AllowDragging
{
get
{
return (bool)GetValue(AllowDraggingProperty);
}
set
{
SetValue(AllowDraggingProperty, value);
}
}
#endregion
#region 뷰 외부 드래그 허용 여부 - AllowDragOutOfView
/// <summary>
/// 뷰 외부 드래그 허용 여부
/// </summary>
public bool AllowDragOutOfView
{
get
{
return (bool)GetValue(AllowDragOutOfViewProperty);
}
set
{
SetValue(AllowDragOutOfViewProperty, value);
}
}
#endregion
#region 드래그 엘리먼트 - ElementBeingDragged
/// <summary>
/// 드래그 엘리먼트
/// </summary>
public UIElement ElementBeingDragged
{
get
{
return !AllowDragging ? null : this.dragElement;
}
protected set
{
if(this.dragElement != null)
{
this.dragElement.ReleaseMouseCapture();
}
if(!AllowDragging)
{
this.dragElement = null;
}
else
{
if(GetCanBeDragged(value))
{
this.dragElement = value;
this.dragElement.CaptureMouse();
}
else
{
this.dragElement = null;
}
}
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 드래그 가능 여부 구하기 - GetCanBeDragged(element)
/// <summary>
/// 드래그 가능 여부 구하기
/// </summary>
/// <param name="element">엘리먼트</param>
/// <returns>드래그 가능 여부</returns>
public static bool GetCanBeDragged(UIElement element)
{
if(element == null)
{
return false;
}
return (bool)element.GetValue(CanBeDraggedProperty);
}
#endregion
#region 드래그 가능 여부 설정하기 - SetCanBeDragged(element, value)
/// <summary>
/// 드래그 가능 여부 설정하기
/// </summary>
/// <param name="element">엘리먼트</param>
/// <param name="value">값</param>
public static void SetCanBeDragged(UIElement element, bool value)
{
if(element != null)
{
element.SetValue(CanBeDraggedProperty, value);
}
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance
//////////////////////////////////////////////////////////////////////////////// Public
#region 전면으로 배치하기 - BringToFront(element)
/// <summary>
/// 전면으로 배치하기
/// </summary>
/// <param name="element">엘리먼트</param>
public void BringToFront(UIElement element)
{
UpdateZOrder(element, true);
}
#endregion
#region 후면으로 배치하기 - SendToBack(element)
/// <summary>
/// 후면으로 배치하기
/// </summary>
/// <param name="element">엘리먼트</param>
public void SendToBack(UIElement element)
{
UpdateZOrder(element, false);
}
#endregion
#region 캔버스 자식 찾기 - FindCanvasChild(dependencyObject)
/// <summary>
/// 캔버스 자식 찾기
/// </summary>
/// <param name="dependencyObject">의존 객체</param>
/// <returns>캔버스 자식</returns>
public UIElement FindCanvasChild(DependencyObject dependencyObject)
{
while(dependencyObject != null)
{
UIElement element = dependencyObject as UIElement;
if(element != null && Children.Contains(element))
{
break;
}
if(dependencyObject is Visual || dependencyObject is Visual3D)
{
dependencyObject = VisualTreeHelper.GetParent(dependencyObject);
}
else
{
dependencyObject = LogicalTreeHelper.GetParent(dependencyObject);
}
}
return dependencyObject as UIElement;
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Protected
#region PREVIEW 마우스 왼쪽 버튼 DOWN 처리하기 - OnPreviewMouseLeftButtonDown(e)
/// <summary>
/// PREVIEW 마우스 왼쪽 버튼 DOWN 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnPreviewMouseLeftButtonDown(e);
this.isDragging = false;
this.dragStartPoint = e.GetPosition(this);
ElementBeingDragged = FindCanvasChild(e.Source as DependencyObject);
if(ElementBeingDragged == null)
{
return;
}
double left = GetLeft (ElementBeingDragged);
double right = GetRight (ElementBeingDragged);
double top = GetTop (ElementBeingDragged);
double bottom = GetBottom(ElementBeingDragged);
this.dragStartOffsetX = ResolveOffset(left, right , out this.modifyOffsetX);
this.dragStartOffsetY = ResolveOffset(top , bottom, out this.modifyOffsetY);
e.Handled = true;
this.isDragging = true;
}
#endregion
#region PREVIEW 마우스 이동시 처리하기 - OnPreviewMouseMove(e)
/// <summary>
/// PREVIEW 마우스 이동시 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnPreviewMouseMove(MouseEventArgs e)
{
base.OnPreviewMouseMove(e);
if(ElementBeingDragged == null || !this.isDragging)
{
return;
}
Point cursorPoint = e.GetPosition(this);
double newOffsetX;
double newOffsetY;
if(this.modifyOffsetX)
{
newOffsetX = this.dragStartOffsetX + (cursorPoint.X - this.dragStartPoint.X);
}
else
{
newOffsetX = this.dragStartOffsetX - (cursorPoint.X - this.dragStartPoint.X);
}
if(this.modifyOffsetY)
{
newOffsetY = this.dragStartOffsetY + (cursorPoint.Y - this.dragStartPoint.Y);
}
else
{
newOffsetY = this.dragStartOffsetY - (cursorPoint.Y - this.dragStartPoint.Y);
}
if(!AllowDragOutOfView)
{
Rect elementRectangle = CalculateDragElementRectangle(newOffsetX, newOffsetY);
bool alignLeft = elementRectangle.Left < 0;
bool alignRight = elementRectangle.Right > ActualWidth;
if(alignLeft)
{
newOffsetX = this.modifyOffsetX ? 0 : ActualWidth - elementRectangle.Width;
}
else if(alignRight)
{
newOffsetX = this.modifyOffsetX ? ActualWidth - elementRectangle.Width : 0;
}
bool alignTop = elementRectangle.Top < 0;
bool alignBottom = elementRectangle.Bottom > ActualHeight;
if(alignTop)
{
newOffsetY = this.modifyOffsetY ? 0 : ActualHeight - elementRectangle.Height;
}
else if(alignBottom)
{
newOffsetY = this.modifyOffsetY ? ActualHeight - elementRectangle.Height : 0;
}
}
if(this.modifyOffsetX)
{
SetLeft(ElementBeingDragged, newOffsetX);
}
else
{
SetRight(ElementBeingDragged, newOffsetX);
}
if(this.modifyOffsetY)
{
SetTop(ElementBeingDragged, newOffsetY);
}
else
{
SetBottom(ElementBeingDragged, newOffsetY);
}
}
#endregion
#region PREVIEW 마우스 UP 처리하기 - OnPreviewMouseUp(e)
/// <summary>
/// PREVIEW 마우스 UP 처리하기
/// </summary>
/// <param name="e">이벤트 인자</param>
protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
{
base.OnPreviewMouseUp(e);
ElementBeingDragged = null;
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Private
#region 드래그 엘리먼트 사각형 계산하기 - CalculateDragElementRectangle(newOffsetX, newOffsetY)
/// <summary>
/// 드래그 엘리먼트 사각형 계산하기
/// </summary>
/// <param name="newOffsetX">신규 오프셋 X</param>
/// <param name="newOffsetY">신규 오프셋 Y</param>
/// <returns>드래그 엘리먼트 사각형</returns>
private Rect CalculateDragElementRectangle(double newOffsetX, double newOffsetY)
{
if(ElementBeingDragged == null)
{
throw new InvalidOperationException("ElementBeingDragged is null.");
}
Size elementSize = ElementBeingDragged.RenderSize;
double x;
double y;
if(this.modifyOffsetX)
{
x = newOffsetX;
}
else
{
x = ActualWidth - newOffsetX - elementSize.Width;
}
if(this.modifyOffsetY)
{
y = newOffsetY;
}
else
{
y = ActualHeight - newOffsetY - elementSize.Height;
}
Point elementPoint = new Point(x, y);
return new Rect(elementPoint, elementSize);
}
#endregion
#region 오프셋 결정하기 - ResolveOffset(side1, side2, useSide1)
/// <summary>
/// 오프셋 결정하기
/// </summary>
/// <param name="side1">측면 1</param>
/// <param name="side2">측면 2</param>
/// <param name="useSide1">측면 1 사용 여부</param>
/// <returns>오프셋</returns>
private static double ResolveOffset(double side1, double side2, out bool useSide1)
{
useSide1 = true;
double result;
if(double.IsNaN(side1))
{
if(double.IsNaN(side2))
{
result = 0;
}
else
{
result = side2;
useSide1 = false;
}
}
else
{
result = side1;
}
return result;
}
#endregion
#region Z 순서 업데이트하기 - UpdateZOrder(element, bringToFront)
/// <summary>
/// Z 순서 업데이트하기
/// </summary>
/// <param name="element">엘리먼트</param>
/// <param name="bringToFront">전면 배치 여부</param>
private void UpdateZOrder(UIElement element, bool bringToFront)
{
if(element == null)
{
return;
}
if(!Children.Contains(element))
{
throw new ArgumentException("Must be a child element of the Canvas.", "element");
}
int elementNewZIndex = -1;
if(bringToFront)
{
foreach(UIElement childElement in Children)
{
if(childElement.Visibility != Visibility.Collapsed)
{
++elementNewZIndex;
}
}
}
else
{
elementNewZIndex = 0;
}
int offset = (elementNewZIndex == 0) ? +1 : -1;
int elementCurrentZIndex = GetZIndex(element);
foreach(UIElement childElement in Children)
{
if(childElement == element)
{
SetZIndex(element, elementNewZIndex);
}
else
{
int zIndex = GetZIndex(childElement);
if(bringToFront && elementCurrentZIndex < zIndex || !bringToFront && zIndex < elementCurrentZIndex)
{
SetZIndex(childElement, zIndex + offset);
}
}
}
}
#endregion
}
}
▶ Country.cs
using System.Windows.Media;
namespace TestProject
{
/// <summary>
/// 국가
/// </summary>
public class Country
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 국가명 - CountryName
/// <summary>
/// 국가명
/// </summary>
public string CountryName { get; set; }
#endregion
#region 국가 이미지 - CountryImage
/// <summary>
/// 국가 이미지
/// </summary>
public ImageSource CountryImage { get; set; }
#endregion
#region 국가 수도 - CountryCapital
/// <summary>
/// 국가 수도
/// </summary>
public string CountryCapital { get; set; }
#endregion
#region 국가 색상 - CountryColor
/// <summary>
/// 국가 색상
/// </summary>
public Color CountryColor { get; set; }
#endregion
}
}
▶ CountryHelper.cs
using System;
using System.Collections.Generic;
using System.Windows.Media;
namespace TestProject
{
/// <summary>
/// 국가 헬퍼
/// </summary>
public class CountryHelper
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 국가 리스트 구하기 - GetCountryList()
/// <summary>
/// 국가 리스트 구하기
/// </summary>
/// <returns>국가 리스트</returns>
public static List<Country> GetCountryList()
{
List<Country> list = new List<Country>
{
new Country
{
CountryName = "아르헨티나",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.ARGENTINA),
CountryCapital = "부에노스 아이레스",
CountryColor = Color.FromRgb(82, 179, 255)
},
new Country
{
CountryName = "호주",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.AUSTRALIA),
CountryCapital = "캔버라",
CountryColor = Color.FromRgb(0, 129, 231)
},
new Country
{
CountryName = "브라질",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.BRAZIL),
CountryCapital = "브라질리아",
CountryColor = Color.FromRgb(255, 250, 0)
},
new Country
{
CountryName = "캐나다",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.CANADA),
CountryCapital = "오타와",
CountryColor = Color.FromRgb(255, 99, 51)
},
new Country
{
CountryName = "중국",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.CHINA),
CountryCapital = "베이징",
CountryColor = Color.FromRgb(255, 99, 51)
},
new Country
{
CountryName = "콜롬비아",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.COLOMBIA),
CountryCapital = "보고타",
CountryColor = Color.FromRgb(255, 250, 0)
},
new Country
{
CountryName = "이집트",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.EGYPT),
CountryCapital = "카이로",
CountryColor = Color.FromRgb(38, 38, 38)
},
new Country
{
CountryName = "영국",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.ENGLAND),
CountryCapital = "런던",
CountryColor = Color.FromRgb(255, 99, 51)
},
new Country
{
CountryName = "핀란드",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.FINLAND),
CountryCapital = "헬싱키",
CountryColor = Color.FromRgb(0, 140, 242)
},
new Country
{
CountryName = "독입",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.GERMANY),
CountryCapital = "베를린",
CountryColor = Color.FromRgb(255, 58, 6)
},
new Country
{
CountryName = "인도",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.INDIA),
CountryCapital = "뉴 델리",
CountryColor = Color.FromRgb(255, 195, 93)
},
new Country
{
CountryName = "케냐",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.KENYA),
CountryCapital = "나이로비",
CountryColor = Color.FromRgb(38, 38, 38)
},
new Country
{
CountryName = "멕시코",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.MEXICO),
CountryCapital = "멕시코 시티",
CountryColor = Color.FromRgb(32, 168, 15)
},
new Country
{
CountryName = "뉴질랜드",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.NEW_ZEALAND),
CountryCapital = "웰링톤",
CountryColor = Color.FromRgb(0, 129, 231)
},
new Country
{
CountryName = "나이제리아",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.NIGERIA),
CountryCapital = "아부자",
CountryColor = Color.FromRgb(32, 168, 15)
},
new Country
{
CountryName = "파키스탄",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.PAKISTAN),
CountryCapital = "이슬라마바드",
CountryColor = Color.FromRgb(32, 168, 15)
},
new Country
{
CountryName = "필리핀",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.PHILIPPINES),
CountryCapital = "마닐라",
CountryColor = Color.FromRgb(0, 123, 225)
},
new Country
{
CountryName = "러시아",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.RUSSIA),
CountryCapital = "모스크바",
CountryColor = Color.FromRgb(0, 123, 225)
},
new Country
{
CountryName = "남아프리카 공화국",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.SOUTH_AFRICA),
CountryCapital = "케이프 타운",
CountryColor = Color.FromRgb(52, 178, 25)
},
new Country
{
CountryName = "미국",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.USA),
CountryCapital = "워싱턴",
CountryColor = Color.FromRgb(0, 123, 225)
},
new Country
{
CountryName = "베트남",
CountryImage = (ImageSource)new ImageSourceConverter().ConvertFrom(ImageConstant.VIETNAM),
CountryCapital = "하노이",
CountryColor = Color.FromRgb(255, 99, 51)
}
};
return GetRandomList(list, 10);
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Private
#region 임의 리스트 구하기 - GetRandomList<T>(itemCount, sourceList)
/// <summary>
/// 임의 리스트 구하기
/// </summary>
/// <typeparam name="TItem">항목 타입</typeparam>
/// <param name="sourceList">소스 리스트</param>
/// <param name="itemCount">항목 수</param>
/// <returns>임의 리스트</returns>
private static List<TItem> GetRandomList<TItem>(List<TItem> sourceList, int itemCount)
{
if(itemCount > sourceList.Count)
{
itemCount = sourceList.Count;
}
List<TItem> list = new List<TItem>(itemCount);
for(var i = 0; i < itemCount; i++)
{
int index = new Random().Next(sourceList.Count);
TItem item = sourceList[index];
sourceList.RemoveAt(index);
list.Add(item);
}
return list;
}
#endregion
}
}
▶ ImageConstant.cs
namespace TestProject
{
/// <summary>
/// 이미지 상수
/// </summary>
public class ImageConstant
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 아르헨티나
/// </summary>
public const string ARGENTINA = "pack://application:,,,/TestProject;component/IMAGE/flag_argentina.png";
/// <summary>
/// 호주
/// </summary>
public const string AUSTRALIA = "pack://application:,,,/TestProject;component/IMAGE/flag_australia.png";
/// <summary>
/// 브라질
/// </summary>
public const string BRAZIL = "pack://application:,,,/TestProject;component/IMAGE/flag_brazil.png";
/// <summary>
/// 캐나다
/// </summary>
public const string CANADA = "pack://application:,,,/TestProject;component/IMAGE/flag_canada.png";
/// <summary>
/// 중국
/// </summary>
public const string CHINA = "pack://application:,,,/TestProject;component/IMAGE/flag_china.png";
/// <summary>
/// 콜롬비아
/// </summary>
public const string COLOMBIA = "pack://application:,,,/TestProject;component/IMAGE/flag_colombia.png";
/// <summary>
/// 이집트
/// </summary>
public const string EGYPT = "pack://application:,,,/TestProject;component/IMAGE/flag_egypt.png";
/// <summary>
/// 영국
/// </summary>
public const string ENGLAND = "pack://application:,,,/TestProject;component/IMAGE/flag_england.png";
/// <summary>
/// 핀란드
/// </summary>
public const string FINLAND = "pack://application:,,,/TestProject;component/IMAGE/flag_finland.png";
/// <summary>
/// 독일
/// </summary>
public const string GERMANY = "pack://application:,,,/TestProject;component/IMAGE/flag_germany.png";
/// <summary>
/// 인디아
/// </summary>
public const string INDIA = "pack://application:,,,/TestProject;component/IMAGE/flag_india.png";
/// <summary>
/// 케냐
/// </summary>
public const string KENYA = "pack://application:,,,/TestProject;component/IMAGE/flag_kenya.png";
/// <summary>
/// 멕시코
/// </summary>
public const string MEXICO = "pack://application:,,,/TestProject;component/IMAGE/flag_mexico.png";
/// <summary>
/// 뉴질랜드
/// </summary>
public const string NEW_ZEALAND = "pack://application:,,,/TestProject;component/IMAGE/flag_new_zealand.png";
/// <summary>
/// 나이제리아
/// </summary>
public const string NIGERIA = "pack://application:,,,/TestProject;component/IMAGE/flag_nigeria.png";
/// <summary>
/// 파키스탄
/// </summary>
public const string PAKISTAN = "pack://application:,,,/TestProject;component/IMAGE/flag_pakistan.png";
/// <summary>
/// 필리핀
/// </summary>
public const string PHILIPPINES = "pack://application:,,,/TestProject;component/IMAGE/flag_philippines.png";
/// <summary>
/// 러시아
/// </summary>
public const string RUSSIA = "pack://application:,,,/TestProject;component/IMAGE/flag_russia.png";
/// <summary>
/// 남아프리카 공화국
/// </summary>
public const string SOUTH_AFRICA = "pack://application:,,,/TestProject;component/IMAGE/flag_south_africa.png";
/// <summary>
/// 미국
/// </summary>
public const string USA = "pack://application:,,,/TestProject;component/IMAGE/flag_usa.png";
/// <summary>
/// 베트남
/// </summary>
public const string VIETNAM = "pack://application:,,,/TestProject;component/IMAGE/flag_vietnam.png";
/// <summary>
/// 세계 맵
/// </summary>
public const string WORLD_MAP = "pack://application:,,,/TestProject;component/IMAGE/world_map.jpg";
#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="Adorner 클래스 : 슬라이딩 어도너 사용하기"
FontFamily="나눔고딕코딩"
FontSize="16">
<Window.Resources>
<Style TargetType="{x:Type local:SlidingAdorner}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:SlidingAdorner}">
<StackPanel Orientation="Vertical">
<Button>
<Button.Template>
<ControlTemplate TargetType="Button">
<Image
Width="48"
Height="48"
Source="{Binding Path=CountryImage}" />
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:SlidingElement}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:SlidingElement}">
<StackPanel>
<Border CornerRadius="4">
<Border.Background>
<LinearGradientBrush Opacity="0.8">
<GradientStop Offset="0.0" Color="Transparent" />
<GradientStop Offset="1.0" Color="{Binding Path=CountryColor}" />
</LinearGradientBrush>
</Border.Background>
<StackPanel Orientation="Vertical">
<Label
Foreground="White"
FontWeight="Bold"
Content="{Binding Path=CountryName}" />
<Label
Foreground="White"
Content="{Binding Path=CountryCapital}" />
</StackPanel>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Name="startButton" Grid.Row="0"
Height="30"
Content="새로 시작하기">
</Button>
<local:DragCanvas x:Name="dragCanvas" Grid.Row="1">
<Canvas.Background>
<ImageBrush
Stretch="Fill"
ImageSource="{Binding Source={x:Static local:ImageConstant.WORLD_MAP}}" />
</Canvas.Background>
</local:DragCanvas>
</Grid>
</Window>
▶ MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace TestProject
{
/// <summary>
/// 메인 윈도우
/// </summary>
public partial class MainWindow
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 국가 리스트 - CountryList
/// <summary>
/// 국가 리스트
/// </summary>
public List<Country> CountryList { get; private set; }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary>
/// 생성자
/// </summary>
public MainWindow()
{
InitializeComponent();
DataContext = this;
Loaded += Window_Loaded;
PreviewMouseLeftButtonDown += Window_PreviewMouseLeftButtonDown;
this.startButton.Click += startButton_Click;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)
/// <summary>
/// 윈도우 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.dragCanvas.Children.Clear();
CountryList = CountryHelper.GetCountryList();
SetDragCanvasData();
}
#endregion
#region 윈도우 PREVIEW 마우스 왼쪽 버튼 DOWN 처리하기 - Window_PreviewMouseLeftButtonDown(sender, e)
/// <summary>
/// 윈도우 PREVIEW 마우스 왼쪽 버튼 DOWN 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
UIElement childElement = this.dragCanvas.FindCanvasChild(e.Source as DependencyObject);
this.dragCanvas.BringToFront(childElement);
}
#endregion
#region 새로 시작하기 버튼 클릭시 처리하기 - startButton_Click(sender, e)
/// <summary>
/// 새로 시작하기 버튼 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void startButton_Click(object sender, RoutedEventArgs e)
{
this.dragCanvas.Children.Clear();
CountryList = CountryHelper.GetCountryList();
SetDragCanvasData();
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 드래그 캔버스 데이터 설정하기 - SetDragCanvasData()
/// <summary>
/// 드래그 캔버스 데이터 설정하기
/// </summary>
private void SetDragCanvasData()
{
Random random = new Random();
foreach(Country country in CountryList)
{
SlidingAdorner slidingAdorner = new SlidingAdorner(country);
slidingAdorner.SetValue(Canvas.LeftProperty, Convert.ToDouble(random.Next(Convert.ToInt32(this.dragCanvas.ActualWidth ))));
slidingAdorner.SetValue(Canvas.TopProperty , Convert.ToDouble(random.Next(Convert.ToInt32(this.dragCanvas.ActualHeight))));
this.dragCanvas.Children.Add(slidingAdorner);
}
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] 대시보드 애니메이션 사용하기 (0) | 2021.09.16 |
---|---|
[C#/WPF] 확장 메뉴 사용하기 (0) | 2021.09.15 |
[C#/WPF] ToggleButton 클래스 : 드롭 다운 버튼/분리 버튼 사용하기 (0) | 2021.09.14 |
[C#/WPF] 열거형 정렬하기 (0) | 2021.09.13 |
[C#/WPF] UserControl 엘리먼트 : 로딩 패널 사용하기 (0) | 2021.09.13 |
[C#/WPF] UserControl 클래스 : 로딩 패널 사용하기 (0) | 2021.09.11 |
[C#/WPF] ImageAwesome 엘리먼트 : Spin/SpinDuration 속성을 사용해 아이콘 회전시키기 (0) | 2021.09.11 |
[C#/WPF] 누겟 설치 : FontAwesome.WPF (0) | 2021.09.11 |
[C#/WPF] GOM 플레이어 모방하기 (0) | 2021.09.05 |
[C#/WPF] LinearGradientBrush 엘리먼트 사용하기 (0) | 2021.08.24 |
댓글을 달아 주세요