일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Winform
- NUnit
- 공공 데이터 포털
- eventargs
- TDD
- 버스 API
- C# 파일 암/복호화
- Excel Cell Format
- 시
- 경기도 버스
- 디자인 패턴
- DrawEllipse
- MDB Connect
- MDB Select
- solid
- Cell Border Style
- 객체지향
- delegate
- C# MDB Handle
- eventhandler
- c#
- Json.NET
- 경기도 버스정보시스템
- GDI+
- C# MDB
- JSON
- sqlite3
- WPF
- MVC
- DrawRectangle
- Today
- Total
White Whale Studio
[WPF] ScrollView Mouse Click & Move 마우스 클릭으로 Child 움직이기 본문
[WPF] ScrollView Mouse Click & Move 마우스 클릭으로 Child 움직이기
glorymind 2015. 1. 21. 17:32WPF ScrollView 에서 기본적으로는 마우스 클릭해서 내부에 있는 컨텐츠 이리저리 굴려봤자 이동을 하지는 않습니다.
다행히도 어떤 친절한 외국 개발자님께서 이미 Y축을 구현해 두셔서 X축을 더하여 완성했습니다.
사용법은 간단합니다.
XAML 창에서 해당 Class가 포함된 프로젝트를 xmlns:my="clr-namespace:PROJECT" 와 같이
참조 추가한 뒤
<ScrollViewer my:TouchScrolling.IsEnabled="True" HorizontalScrollBarVisibility="Auto" Margin="0,0,0,30" VerticalScrollBarVisibility="Auto" Name="sv_image" CanContentScroll="True">
이런식으로 스크롤 뷰어에 my:TouchScrolling.IsEnabled="True" 항목만 추가하시면
간단하게 구현 끝~!
간만에 보는 깔끔한 코드라 기분이 좋습니다 ㅎ.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | public class TouchScrolling : DependencyObject { public static bool GetIsEnabled(DependencyObject obj) { return (bool)obj.GetValue(IsEnabledProperty); } public static void SetIsEnabled(DependencyObject obj, bool value) { obj.SetValue(IsEnabledProperty, value); } public bool IsEnabled { get { return (bool)GetValue(IsEnabledProperty); } set { SetValue(IsEnabledProperty, value); } } public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(TouchScrolling), new UIPropertyMetadata(false, IsEnabledChanged)); static Dictionary<object, MouseCapture> _captures = new Dictionary<object, MouseCapture>(); static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var target = d as ScrollViewer; if (target == null) return; if ((bool)e.NewValue) { target.Loaded += target_Loaded; } else { target_Unloaded(target, new RoutedEventArgs()); } } static void target_Unloaded(object sender, RoutedEventArgs e) { System.Diagnostics.Debug.WriteLine("Target Unloaded"); var target = sender as ScrollViewer; if (target == null) return; _captures.Remove(sender); target.Loaded -= target_Loaded; target.Unloaded -= target_Unloaded; target.PreviewMouseLeftButtonDown -= target_PreviewMouseLeftButtonDown; target.PreviewMouseMove -= target_PreviewMouseMove; target.PreviewMouseLeftButtonUp -= target_PreviewMouseLeftButtonUp; } static void target_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var target = sender as ScrollViewer; if (target == null) return; _captures[sender] = new MouseCapture { VerticalOffset = target.VerticalOffset, Point = e.GetPosition(target), }; } static void target_Loaded(object sender, RoutedEventArgs e) { var target = sender as ScrollViewer; if (target == null) return; System.Diagnostics.Debug.WriteLine("Target Loaded"); target.Unloaded += target_Unloaded; target.PreviewMouseLeftButtonDown += target_PreviewMouseLeftButtonDown; target.PreviewMouseMove += target_PreviewMouseMove; target.PreviewMouseLeftButtonUp += target_PreviewMouseLeftButtonUp; } static void target_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { var target = sender as ScrollViewer; if (target == null) return; target.ReleaseMouseCapture(); } static void target_PreviewMouseMove(object sender, MouseEventArgs e) { if (!_captures.ContainsKey(sender)) return; if (e.LeftButton != MouseButtonState.Pressed) { _captures.Remove(sender); return; } var target = sender as ScrollViewer; if (target == null) return; var capture = _captures[sender]; var point = e.GetPosition(target); var dy = point.Y - capture.Point.Y; // Y축 이동 if (Math.Abs(dy) > 5) { target.CaptureMouse(); } var dx = point.X - capture.Point.X; // X축 이동 if (Math.Abs(dx) > 5) { target.CaptureMouse(); } target.ScrollToVerticalOffset(capture.VerticalOffset - dy); // Y축 이동 상하 target.ScrollToHorizontalOffset(capture.VerticalOffset - dx); // X축 이동 좌우 } internal class MouseCapture { public Double VerticalOffset { get; set; } public Point Point { get; set; } } } | cs |
public class TouchScrolling : DependencyObject
{
public static bool GetIsEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsEnabledProperty);
}
public static void SetIsEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsEnabledProperty, value);
}
public bool IsEnabled
{
get { return (bool)GetValue(IsEnabledProperty); }
set { SetValue(IsEnabledProperty, value); }
}
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(TouchScrolling), new UIPropertyMetadata(false, IsEnabledChanged));
static Dictionary<object, MouseCapture> _captures = new Dictionary<object, MouseCapture>();
static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = d as ScrollViewer;
if (target == null) return;
if ((bool)e.NewValue)
{
target.Loaded += target_Loaded;
}
else
{
target_Unloaded(target, new RoutedEventArgs());
}
}
static void target_Unloaded(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Target Unloaded");
var target = sender as ScrollViewer;
if (target == null) return;
_captures.Remove(sender);
target.Loaded -= target_Loaded;
target.Unloaded -= target_Unloaded;
target.PreviewMouseLeftButtonDown -= target_PreviewMouseLeftButtonDown;
target.PreviewMouseMove -= target_PreviewMouseMove;
target.PreviewMouseLeftButtonUp -= target_PreviewMouseLeftButtonUp;
}
static void target_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var target = sender as ScrollViewer;
if (target == null) return;
_captures[sender] = new MouseCapture
{
VerticalOffset = target.VerticalOffset,
Point = e.GetPosition(target),
};
}
static void target_Loaded(object sender, RoutedEventArgs e)
{
var target = sender as ScrollViewer;
if (target == null) return;
System.Diagnostics.Debug.WriteLine("Target Loaded");
target.Unloaded += target_Unloaded;
target.PreviewMouseLeftButtonDown += target_PreviewMouseLeftButtonDown;
target.PreviewMouseMove += target_PreviewMouseMove;
target.PreviewMouseLeftButtonUp += target_PreviewMouseLeftButtonUp;
}
static void target_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var target = sender as ScrollViewer;
if (target == null) return;
target.ReleaseMouseCapture();
}
static void target_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (!_captures.ContainsKey(sender)) return;
if (e.LeftButton != MouseButtonState.Pressed)
{
_captures.Remove(sender);
return;
}
var target = sender as ScrollViewer;
if (target == null) return;
var capture = _captures[sender];
var point = e.GetPosition(target);
var dy = point.Y - capture.Point.Y; // Y축 이동
if (Math.Abs(dy) > 5)
{
target.CaptureMouse();
}
var dx = point.X - capture.Point.X; // X축 이동
if (Math.Abs(dx) > 5)
{
target.CaptureMouse();
}
target.ScrollToVerticalOffset(capture.VerticalOffset - dy); // Y축 이동 상하
target.ScrollToHorizontalOffset(capture.VerticalOffset - dx); // X축 이동 좌우
}
internal class MouseCapture
{
public Double VerticalOffset { get; set; }
public Point Point { get; set; }
}
}
'IT Engineering > .Net (WPF)' 카테고리의 다른 글
[C#/WPF] FTP - DownLoad Files / 파일 다운로드 (0) | 2015.04.02 |
---|---|
Distinct 구현 (0) | 2015.04.02 |
[WPF] WCF ServiceModel 클라이언트 구성 섹션에서 'IService1' 계약을 참조하는 기본 끝점 요소가 없습니다. (0) | 2014.12.30 |
[ClickOnce 배포 오류] (1) | 2014.08.11 |
csExWB WebBrowser Control DLL Error (0) | 2014.07.07 |