Microsoft-ui-xaml: ๋” ์œ ์—ฐํ•œ ScrollViewer

์— ๋งŒ๋“  2018๋…„ 12์›” 19์ผ  ยท  61์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: microsoft/microsoft-ui-xaml

์ด๊ฒƒ์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ๋˜๋Š” API ์ œ์•ˆ์„ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด ์œ ํ˜•์— ๋Œ€ํ•œ ์ƒˆ API๋ฅผ ์ œ์•ˆํ•˜๊ฑฐ๋‚˜ ์ƒˆ UI ์ปจํŠธ๋กค์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋ฅผ ์ œ์•ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์„ธ๋ถ€ ์‚ฌํ•ญ์ด ์—†์–ด๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ์š”์•ฝ ๋ฐ ๊ทผ๊ฑฐ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋งํฌ๋Š” WinUI ๊ธฐ๋Šฅ/API ์ œ์•ˆ ํ”„๋กœ์„ธ์Šค๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. https://github.com/Microsoft/microsoft-ui-xaml-specs/blob/master/docs/feature_proposal_process.md ๊ธฐ๋Šฅ ๋˜๋Š” API ์ œ์•ˆ์— ๋Œ€ํ•œ ์ œ๋ชฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์งง๊ณ  ๊ตฌ์ฒด์ ์œผ๋กœ ๊ธฐ์ˆ ํ•ด ์ฃผ์‹ญ์‹œ์˜ค.

์ œ์•ˆ: ์Šคํฌ๋กค ๋ทฐ์–ด

์š”์•ฝ

tl:dr; Win10์˜ ํ•˜์œ„ ๋ฆด๋ฆฌ์Šค๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•  ๋•Œ ์—ฌ์ „ํžˆ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐํ•˜๋ฉด์„œ๋„ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ์Šคํฌ๋กค ๋ฐ ํ™•๋Œ€/์ถ•์†Œ ์ปจํŠธ๋กค์„ XAML์—์„œ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ScrollViewer ์ปจํŠธ๋กค์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์ปจํŠธ๋กค(ํ”Œ๋žซํผ ๋ฐ ๋น„ํ”Œ๋žซํผ ๋ชจ๋‘)์— ๋Œ€ํ•œ ๊ธฐ๋ณธ์ ์ธ ์Šคํฌ๋กค ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ๋ชจ๋“  UI์—์„œ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ปจํŠธ๋กค์€ ๊ธฐ๋ณธ ์ •์ฑ… ๋ฐ UX(์˜ˆ: ์˜์‹ ์Šคํฌ๋กค ๋ง‰๋Œ€, ํฌ์ปค์Šค/ํ‚ค๋ณด๋“œ ์ƒํ˜ธ ์ž‘์šฉ, ์ ‘๊ทผ์„ฑ, ๊ธฐ๋ณธ ์Šคํฌ๋กค ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋“ฑ)์™€ ํ•จ๊ป˜ ์ด๋™ ๋ฐ ํ™•๋Œ€/์ถ•์†Œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ผ์ƒ์ ์ธ ์•ฑ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์—์„œ ์Šคํฌ๋กค ๊ธฐ๋ฐ˜ ์ปจํŠธ๋กค์˜ ํ•ต์‹ฌ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋˜๊ณ  ๋งค์šฐ ๊ณ ๊ธ‰ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์„œ๋น„์Šคํ•  ์ˆ˜ ์žˆ์„ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ์œ ์—ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์ œ์–ด๋Š” ์ด๋Ÿฌํ•œ ์ˆ˜์ค€์˜ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๋ก ์  ํ•ด์„

๋ชจ๋“  ๊ฐœ๋ฐœ์ž์™€ ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ด ์ด ๊ธฐ๋Šฅ์„ WinUI์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋ฅผ ์„ค๋ช…ํ•˜์‹ญ์‹œ์˜ค. ํ•ด๋‹น๋˜๋Š” ๊ฒฝ์šฐ ํ˜„์žฌ WinUI ๋กœ๋“œ๋งต ๋ฐ ์šฐ์„  ์ˆœ์œ„์— ์–ด๋–ป๊ฒŒ ๋ถ€ํ•ฉํ•˜๋Š”์ง€ ์„ค๋ช…ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/Microsoft/microsoft-ui-xaml-specs/blob/master/docs/roadmap.md

ํ•ต์‹ฌ ํ”Œ๋žซํผ์˜ ๊ณต๊ฐœ API ์œ„์— ๊ณ„์ธตํ™”๋œ ๋ฐฉ์‹์œผ๋กœ ScrollViewer ์ปจํŠธ๋กค์„ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ค‘์š”ํ•œ ๋””๋”ค๋Œ์ž…๋‹ˆ๋‹ค.

  1. ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋กœ ๋” ๋งŽ์€ ์ œ์–ด ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋ฏผ์ฒฉ์„ฑ ์ฆ๊ฐ€).
  2. ์ƒ์œ„ ์ˆ˜์ค€ ํ”„๋ ˆ์ž„์›Œํฌ ์„œ๋น„์Šค(์˜ˆ: ์ ‘๊ทผ์„ฑ)์˜ ์ด์ ๊ณผ ๊ฒฐํ•ฉ๋œ ํ•˜์œ„ ์ˆ˜์ค€ ํ”Œ๋žซํผ ๊ธฐ๋Šฅ์˜ ์œ ์—ฐ์„ฑ์„ ํ‘œ์‹œํ•˜๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ์ œ์–ด ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  3. ์ด์ „ ๋ฒ„์ „์˜ Win10์—์„œ XAML์˜ ์ตœ์‹  ์Šคํฌ๋กค ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ์ผค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด ์ปจํŠธ๋กค์€ 1) UWP ๋‚ด์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ณ , 2) ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ณ ์œ ํ•œ ์Šคํฌ๋กค ๊ฒฝํ—˜์„ ์ƒ์„ฑํ•  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ์ˆ˜์ค€์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์œผ๋ฉฐ, 3) ๋Œ€์ฒด๋˜๋Š” DirectManipulation API ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Win8์—์„œ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. UWP์˜ ์ตœ์‹  InteractionTracker API๋กœ

๊ธฐ์กด ScrollViewer ์ปจํŠธ๋กค์„ ์žˆ๋Š” ๊ทธ๋Œ€๋กœ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์€ ์‹œ์ž‘์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋Œ€์‹  ์ปจํŠธ๋กค์€ InteractionTracker ์˜ ์ตœ์‹ (๋ฐ ์ด๋ฏธ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ) ๊ธฐ๋Šฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฑฐ์˜ ๋™์ผํ•œ API ํ‘œ๋ฉด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ƒ์œ„ ๊ณ„ํš

_Windows_.UI.Xaml.Controls ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ๊ธฐ์กด ScrollViewer๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค(์ค‘์š”ํ•œ ๋ฒ„๊ทธ ์ˆ˜์ • ์ œ์™ธ).

์ƒˆ ScrollViewer๋Š” _Microsoft_.UI.Xaml.Controls ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žˆ์Šต๋‹ˆ๋‹ค. API๋Š” ๋Œ€๋ถ€๋ถ„ _Windows_ ๋ฒ„์ „๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๋ถ„๋ช…ํ•œ ์ด์ ์ด ์žˆ๋Š” ๊ฒฝ์šฐ(๊ณตํ†ต ์‹œ๋‚˜๋ฆฌ์˜ค ๋‹จ์ˆœํ™”, ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ๋„์ž… ๋“ฑ) ์ปจํŠธ๋กค์˜ API๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ScrollViewer์™€ ํ•จ๊ป˜ Microsoft.UI.Xaml.Controls._Primitives_ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žˆ๋Š” ์ƒˆ๋กœ์šด ์œ ํ˜•์ธ Scroller๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. Scroller๋Š” InteractionTracker ์˜ ๊ธฐ๋Šฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ XAML์—์„œ ์Šคํฌ๋กค ๋ฐ ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ์œ„ํ•œ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋‘ ์ปจํŠธ๋กค์˜ ์ดˆ๊ธฐ ๋ชฉํ‘œ๋Š” ๋‹ค์Œ ๊ณต์‹ ๋ฆด๋ฆฌ์Šค์˜ ์ผ๋ถ€๋กœ ํ’ˆ์งˆ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•œ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ์–ป๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์™„๋ฃŒ๋˜์ง€ ์•Š์€ API๋Š” '๋ฏธ๋ฆฌ๋ณด๊ธฐ'๋กœ ์œ ์ง€๋˜๋ฉฐ ์‹œํ—˜ํŒ โ€‹โ€‹ํŒจํ‚ค์ง€์˜ ์ผ๋ถ€๋กœ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

-------------------- ์•„๋ž˜ ์„น์…˜์€ ์•„์ด๋””์–ด๋‚˜ ์ œ์•ˆ์„œ๋ฅผ ์ œ์ถœํ•  ๋•Œ ์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. PR์„ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ ์ „์— ๋ชจ๋“  ์„น์…˜์ด ํ•„์š”ํ•˜์ง€๋งŒ ํ† ๋ก ์„ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ----------------------

๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ


| # | ๊ธฐ๋Šฅ | | ์šฐ์„ ์ˆœ์œ„ |
|:-:|:--|-|:-:|
| 1 | ๊ธฐ์กด ScrollViewer์™€ ์ผ์น˜ํ•˜๋Š” ๊ธฐ๋ณธ UX๋กœ _๋น„๋ฐ€๋ด‰_, ์ด๋™ ๋ฐ ํ™•๋Œ€/์ถ•์†Œ ์ œ์–ด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. || ํ•„์ˆ˜ |
| 2 | ๊ณต๊ฐœ๋œ ํ”Œ๋žซํผ ์ง€์› API์—๋งŒ ์˜์กดํ•˜์—ฌ ํ”Œ๋žซํผ ๊ธฐ๋Šฅ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. || ํ•„์ˆ˜ |
| 3 | ํ”„๋ ˆ์ž„์›Œํฌ ์ˆ˜์ค€ XAML ์„œ๋น„์Šค์™€ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด:
- ์‹œ์Šคํ…œ ํฌ์ปค์Šค๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
- ์ดˆ์ ์ด ๋งž์ถฐ์ง„ ์š”์†Œ๋ฅผ ์ž๋™์œผ๋กœ ๋ณด๊ธฐ(ํ‚ค๋ณด๋“œ, ๊ฒŒ์ž„ํŒจ๋“œ, ์Šคํฌ๋ฆฐ ๋ฆฌ๋”)
- ํšจ๊ณผ์ ์ธ ๋ทฐํฌํŠธ ๋ณ€๊ฒฝ์— ์ฐธ์—ฌ
- ์Šคํฌ๋กค ๊ณ ์ • ์ง€์› || ํ•„์ˆ˜|
| 4 | ์ž…๋ ฅ ๊ธฐ๋ฐ˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ || ํ•„์ˆ˜ |
| 5 | ์ด๋ฏธ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์žˆ๋Š” ๊ธฐ์กด ์Šคํฌ๋กค ์ข…์† ์ปจํŠธ๋กค(์˜ˆ: ParallaxView, RefreshContainer, SwipeControl)๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. || ํ•„์ˆ˜ |
| 6 | ๊ด€์„ฑ ๋ณด๊ธฐ ๋ณ€๊ฒฝ(์˜ˆ: ์‚ฌ์šฉ์ž ์ง€์ • ์• ๋‹ˆ๋ฉ”์ด์…˜ ์Šคํฌ๋กค ๋˜๋Š” ํ™•๋Œ€/์ถ•์†Œ)์— ๋Œ€ํ•œ ๊ณก์„ ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. || ํ•„์ˆ˜ |
| 7 | ์ ˆ๋Œ€ ๋˜๋Š” ์ƒ๋Œ€ ์˜คํ”„์…‹์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณด๊ธฐ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ๊ด€์‹ฌ ์ง€์ ์œผ๋กœ ์Šคํฌ๋กค) || ํ•„์ˆ˜ |
| 8 | ์ž„ํŽ„์Šค/์ถ”๊ฐ€ ์†๋„๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณด๊ธฐ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ(์˜ˆ: ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ ๋˜๋Š” ๋งˆ์šฐ์Šค ์„ ํƒ ์ง์‚ฌ๊ฐํ˜•์„ ํ†ตํ•œ ๋‹ค์ค‘ ์„ ํƒ ์ค‘ ์ž๋™ ๋ถ€๋“œ๋Ÿฌ์šด ์Šคํฌ๋กค) || ํ•„์ˆ˜ |
| 9 | ์˜ค๋ฒ„ํŒฌ๊ณผ ๊ทธ ์ •๋„๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์Œ || ํ•„์ˆ˜ |
| 10 | ์Šคํฌ๋กค ์ƒํƒœ์˜ ๋ณ€ํ™”๋ฅผ ๊ด€์ฐฐํ•˜๊ณ  ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์Œ || ํ•„์ˆ˜ |
| 11 | ์Šค๋ƒ… ํฌ์ธํŠธ ์Šคํฌ๋กค ๋ฐ ํ™•๋Œ€/์ถ•์†Œ ์ง€์›. || ํ•ด์•ผ |
| 12 | ์‚ฌ์šฉ์ž ์ง€์ • "์Šคํฌ๋กค ๋ง‰๋Œ€" ์ปจํŠธ๋กค์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํฌ๋กค์„ ๊ตฌ๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ์‚ฌ์ง„ ํƒ€์ž„๋ผ์ธ ์Šคํฌ๋Ÿฌ๋ฒ„). || ํ•ด์•ผ |
| 13 | ํŠน์ • ์ž…๋ ฅ ์œ ํ˜•์„ ๋ฌด์‹œํ•˜๋„๋ก ์ปจํŠธ๋กค์„ ์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ํ„ฐ์น˜ ๋˜๋Š” ํŽœ์— ์‘๋‹ตํ•˜์ง€๋งŒ ๋งˆ์šฐ์Šค ํœ  ์ž…๋ ฅ์€ ๋ฌด์‹œ). || ํ•ด์•ผ |
| 14 | ์Šคํฌ๋กค ์œ„์น˜๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ณต์›ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ๊ฐ€์ƒํ™” ๋ชฉ๋ก์—์„œ) || ํ•ด์•ผ |
| 15 | ๊ณ ์ • ํ—ค๋”/์š”์†Œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. || ํ•ด์•ผ |
| 16 | ์‚ฌ์šฉ์ž๊ฐ€ ๋น ๋ฅด๊ฒŒ ์—ฐ์†์ ์œผ๋กœ ๋ฐ˜๋ณต๋˜๋Š” ์ œ์Šค์ฒ˜๋ฅผ ํ•  ๋•Œ ๊ฐ€์† ์Šคํฌ๋กค์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค . || ํ•ด์•ผ |
| 17 | ๋งˆ์šฐ์Šค ๊ฐ€์šด๋ฐ ํด๋ฆญ ๋ฐ ์Šคํฌ๋กค ์„ ์ง€์›ํ•˜๋Š” ๊ธฐ๋ณธ UX๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. |mousewheel panning | ํ•ด์•ผ |
| 18 | ๋งˆ์šฐ์Šค๋ฅผ ํ†ตํ•ด ํด๋ฆญ ๋ฐ ์ด๋™ํ•˜๋Š” ๋ชจ๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: PDF ๋ทฐ์–ด ๋‚ด์—์„œ ์ฝ˜ํ…์ธ  ์ด๋™). |mouse hand cursor for panning | ํ•ด์•ผ |
| 19 | ์‚ฌ์šฉ์ž ์ •์˜ ์ปจํŠธ๋กค์„ ์‚ฌ์šฉํ•˜์—ฌ ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ๊ตฌ๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ํ™•๋Œ€/์ถ•์†Œ ์Šฌ๋ผ์ด๋”). || ํ•ด์•ผ |
| 20 | ์Šคํฌ๋กค ๊ฐ€๋Šฅ ์˜์—ญ์— ํฌํ•จ๋œ ์ฝ˜ํ…์ธ ๋ฅผ ์ธ์‡„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. || ํ•ด์•ผ |
| 21 | ํšŒ์ „ ์ œ์Šค์ฒ˜๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. || ์ˆ˜ |
| 22 | ๊นœ๋ฐ•์ž„ ๋ฐ ๋ฒ„๋ฒ…๊ฑฐ๋ฆผ ์—†๋Š” ์Šคํฌ๋กค๋กœ ๋‘˜ ์ด์ƒ์˜ ์˜์—ญ์„ ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ํ…์ŠคํŠธ ์ฐจ์ด ์‹œ๋‚˜๋ฆฌ์˜ค). || ์ˆ˜ |
| 23 | ์ž…๋ ฅ ๊ธฐ๋ฐ˜ ๋ณด๊ธฐ ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ณก์„ ์„ ์‚ฌ์šฉ์ž ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ์ค‘๋ ฅ ์šฐ๋ฌผ๊ณผ ๊ฐ™์€ ์†๊ฐ€๋ฝ ์•„๋ž˜๋กœ ๋™์ž‘ ์ •์˜). || ์ˆ˜ |
| 24 | ์œ„๋กœ ์Šคํฌ๋กค ๋˜๋Š” ์•„๋ž˜๋กœ ์Šคํฌ๋กค์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค . || ์ˆ˜ |
| 25 | ์˜ค๋ฒ„ํŒจ๋‹์„ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. || ์ˆ˜ |
| 26 | UIElement์˜ ManipulationMode ์†์„ฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ScrollViewer ๋‚ด์—์„œ ์ฝ˜ํ…์ธ ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค . || ์ˆ˜ |
| 27 | ๊ด€์„ฑ ๋ฐ/๋˜๋Š” ๊ด€์„ฑ์—์„œ ํŠ€๋Š” ๊ธฐ๋Šฅ์„ ๋Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. || ์ˆ˜|
| 28 | ์ฝ˜ํ…์ธ  ์ž๋ฅด๊ธฐ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: CanContentRenderOutsideBounds ). || ์ˆ˜ |
| 29 | ๋ทฐ ๋ณ€๊ฒฝ์˜ ๋์—์„œ ์™„๋ฃŒ ์ด์œ ๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. || ์ˆ˜ |

์ˆ ์–ด

  • _Overpan_ ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ˜ํ…์ธ  ํฌ๊ธฐ ์ด์ƒ์œผ๋กœ ์ด๋™ํ•˜๊ฑฐ๋‚˜ ํ™•๋Œ€/์ถ•์†Œํ•˜๋ ค๊ณ  ํ•˜๋ฉด ํƒ„์„ฑ/๊ณ ๋ฌด ๋ฐด๋“œ ํšจ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.
  • _Railing_ ์€ ์Šคํฌ๋กค๋Ÿฌ๊ฐ€ ์ดˆ๊ธฐ ์ œ์Šค์ฒ˜์˜ ๋ฐฉํ–ฅ์— ๋”ฐ๋ผ "์„ ํ˜ธํ•˜๋Š”" ์ถ•์œผ๋กœ์˜ ์›€์ง์ž„์„ ์ž๋™์œผ๋กœ ์ž ๊ธ€ ๋•Œ์ž…๋‹ˆ๋‹ค.
  • _Chaining_ ์€ ๋‹ค๋ฅธ ํ‘œ๋ฉด ์•ˆ์— ์ค‘์ฒฉ๋œ scrollabe ํ‘œ๋ฉด์ด ์žˆ๊ณ  ๋‚ด๋ถ€์˜ ์Šคํฌ๋กค ์ด๋™์ด ๊ทธ ๋ฒ”์œ„์— ๋„๋‹ฌํ•˜๋ฉด ์™ธ๋ถ€ ํ‘œ๋ฉด์—์„œ ๊ณ„์†ํ•˜๋„๋ก ์Šน๊ฒฉ๋˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.
  • _์Šค๋ƒ… ํฌ์ธํŠธ_ ๋Š” ๊ด€์„ฑ ์Šคํฌ๋กค(์ฆ‰, ์‚ฌ์šฉ์ž๊ฐ€ ์†๊ฐ€๋ฝ์„ ๋—€ ํ›„ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์Šคํฌ๋กค)์ด ๋๋‚˜๋ฉด ๋ทฐํฌํŠธ๊ฐ€ ์ •์ง€ํ•˜๋Š” ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ  ๋‚ด์˜ ์œ„์น˜์ž…๋‹ˆ๋‹ค. FlipView์™€ ๊ฐ™์€ ์ปจํŠธ๋กค์—๋Š” ์Šค๋ƒ… ํฌ์ธํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • _Scroll anchoring_ ์€ ํ‘œ์‹œ๋˜๋Š” ์ฝ˜ํ…์ธ ์˜ ์ƒ๋Œ€์  ์œ„์น˜๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ทฐํฌํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. ๋ ˆ์ด์•„์›ƒ์œผ๋กœ ์ธํ•œ ์ฝ˜ํ…์ธ  ์œ„์น˜ ๋˜๋Š” ํฌ๊ธฐ์˜ ๊ฐ‘์ž‘์Šค๋Ÿฌ์šด ์ด๋™์œผ๋กœ ์ธํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์˜ํ–ฅ์„ ๋ฐ›๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ์‚ฌ๋ฅผ ์ฝ๊ณ  ์žˆ๊ณ  ์ž ์‹œ ํ›„ ๊ธฐ์‚ฌ ์ƒ๋‹จ์˜ ์ด๋ฏธ์ง€/๊ด‘๊ณ ๊ฐ€ ๋งˆ์นจ๋‚ด ๋กœ๋“œ๋˜์–ด ๋ชจ๋“  ๊ฒƒ์ด ์•„๋ž˜๋กœ ์ด๋™ํ•จ) . ์Šคํฌ๋กค ์•ต์ปค๋ง์€ ๋‹ค์–‘ํ•œ ํฌ๊ธฐ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ UI ๊ฐ€์ƒํ™”๋ฅผ ์œ„ํ•œ ํ•„์ˆ˜ ์š”์†Œ์ž…๋‹ˆ๋‹ค.
  • _์ค‘๋ ฅ ์šฐ๋ฌผ_ ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ˜ํ…์ธ ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๋™์•ˆ(์ฆ‰, ์‚ฌ์šฉ์ž์˜ ์†๊ฐ€๋ฝ์ด ์•„๋ž˜๋กœ ๋‚ด๋ ค๊ฐ„ ๊ฒฝ์šฐ) ์Šคํฌ๋กค ๋™์ž‘์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ  ๋‚ด์˜ ์œ„์น˜์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ค‘๋ ฅ ์šฐ๋ฌผ์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋Šฅ๋™์ ์œผ๋กœ ์ด๋™ํ•˜๊ฑฐ๋‚˜ ํ™•๋Œ€/์ถ•์†Œํ•  ๋•Œ ์›€์ง์ž„์ด ๋Š๋ ค์ง€๊ฑฐ๋‚˜ ๋นจ๋ผ์ง€๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ์Šคํฌ๋กค๋ง์˜ ๊ฐ์ง€๋œ ๋งˆ์ฐฐ์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์˜ˆ

๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๋Š” ํ•˜๋‚˜ ์ด์ƒ์˜ ์˜ˆ๋ฅผ ํฌํ•จํ•˜์‹ญ์‹œ์˜ค. ๋„์›€์ด ๋˜๋Š” ๊ฒฝ์šฐ ์ฝ”๋“œ ์˜ˆ์ œ ๋˜๋Š” ์Šคํฌ๋ฆฐ์ƒท์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋จธ๋ฆฌ๋ง

๊ธฐ๋ณธ์ ์œผ๋กœ ScrollViewer๋Š” ์ฝ˜ํ…์ธ ์˜ ํฌ๊ธฐ๊ฐ€ ๋ทฐํฌํŠธ๋ณด๋‹ค ํด ๋•Œ ์ฝ˜ํ…์ธ ์— ๋Œ€ํ•œ ํŒจ๋‹์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ฝ˜ํ…์ธ ์˜ ํฌ๊ธฐ๋Š” XAML์˜ ๋ ˆ์ด์•„์›ƒ ์‹œ์Šคํ…œ์— ์˜ํ•ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ์žˆ๋Š” ์˜ˆ์ œ๋Š” ํ˜„์žฌ ScrollViewer์™€ ์ƒˆ ScrollViewer ๊ฐ„์˜ ์ฃผ์š” API ์ฐจ์ด์ ์„ ๊ฐ•์กฐํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์„ธ๋กœ ์Šคํฌ๋กค(์ฐจ์ด ์—†์Œ)

์ฝ˜ํ…์ธ ์˜ ๋„ˆ๋น„๋Š” ๋ทฐํฌํŠธ์™€ ๋™์ผํ•˜๋„๋ก ์ž๋™์œผ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ๋†’์ด๋Š” ์ œํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋ทฐํฌํŠธ์˜ ๋†’์ด๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ์‚ฌ์šฉ์ž๋Š” ๋‹ค์–‘ํ•œ ์ž…๋ ฅ ๋ฐฉ์‹์„ ํ†ตํ•ด ํŒฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<ScrollViewer Width="500" Height="400">
    <ItemsRepeater ItemsSource="{x:Bind ViewModel.Items}" ItemTemplate="{StaticResource MyTemplate}"/>
</ScrollViewer>

์ˆ˜ํ‰ ์Šคํฌ๋กค

์ด๋Š” ์ด์ „์— HorizontalScrollBarVisibility๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ–ˆ๋˜ ๊ธฐ์กด ScrollViewer์—์„œ ์˜๋„์ ์œผ๋กœ ๋ฒ—์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค. ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์„ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

<ScrollViewer Width="500" Height="400" ContentOrientation="Horizontal">
    <StackPanel Orientation="Horizontal">
        <!-- ... -->
    </StackPanel>
</ScrollViewer>

_ContentOrientation_ ์†์„ฑ์„ ์„ค์ •ํ•˜๋ฉด ๊ฐ€๋กœ ์ „์šฉ ์Šคํฌ๋กค์ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. ๋ ˆ์ด์•„์›ƒ ์ค‘์— ์ฝ˜ํ…์ธ ์— ์‚ฌ์šฉ๋˜๋Š” ์ œ์•ฝ ์กฐ๊ฑด์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. Horizontal ๊ฐ’์€ ์ฝ˜ํ…์ธ ๊ฐ€ ์ˆ˜ํ‰์œผ๋กœ ์ œํ•œ๋˜์ง€ ์•Š๊ณ (๋ฌดํ•œํ•œ ํฌ๊ธฐ ํ—ˆ์šฉ) ๋ทฐํฌํŠธ์™€ ์ผ์น˜ํ•˜๋„๋ก ์ˆ˜์ง์œผ๋กœ ์ œํ•œ๋จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ˆ˜์ง(๊ธฐ๋ณธ๊ฐ’)์€ ์ˆ˜์ง์œผ๋กœ ๊ตฌ์†๋˜์ง€ ์•Š๊ณ  ์ˆ˜ํ‰์œผ๋กœ ๊ตฌ์†๋จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

ํฐ ์ด๋ฏธ์ง€ ์Šคํฌ๋กค

_Both_์˜ ContentOrientation์€ ์ฝ˜ํ…์ธ ๊ฐ€ ์ˆ˜ํ‰ ๋ฐ ์ˆ˜์ง์œผ๋กœ ์ œํ•œ๋˜์ง€ ์•Š์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

<ScrollViewer Width="500" Height="400" ContentOrientation="Both">
    <Image Source="Assets/LargeEiffelTower.png"/>
</ScrollViewer>

ScrollBar ๊ฐ€์‹œ์„ฑ ๋ณ€๊ฒฝ

์ด ์˜ˆ์—์„œ๋Š” ํ•ญ์ƒ ๋‘ ์Šคํฌ๋กค ๋ง‰๋Œ€๋ฅผ ๋ชจ๋‘ ์ˆจ๊น๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์—ฌ์ „ํžˆ ์–ด๋Š ๋ฐฉํ–ฅ์œผ๋กœ๋“  ์ฝ˜ํ…์ธ ๋ฅผ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<ScrollViewer Width="500" Height="400"
              ContentOrientation="Both"
              HorizontalScrollBarVisibility="Hidden"
              VerticalScrollBarVisibility="Hidden">
    <Image Source="Assets/LargeEiffelTower.png"/>
</ScrollViewer>

ํŠน์ • ์œ ํ˜•์˜ ์ž…๋ ฅ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์ œ๊ณต ์ง€์› ๋„๊ธฐ

์ด ์˜ˆ์—์„œ ๊ฐœ๋ฐœ์ž๋Š” ๋งˆ์šฐ์Šค ํœ  ์ž…๋ ฅ์— ๋Œ€ํ•ด ์‚ฌ์šฉ์ž ์ง€์ • ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ํŽœ์„ ํ†ตํ•ด ์˜ฌ๊ฐ€๋ฏธ ์„ ํƒ ํ™˜๊ฒฝ์„ ์ง€์›ํ•˜๋Š” ์บ”๋ฒ„์Šค ๊ธฐ๋ฐ˜ ์•ฑ์„ ๋งŒ๋“ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Touch์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์œ ํ˜•์€ ํ—ˆ์šฉํ•˜๋ฉด์„œ ์ด๋Ÿฌํ•œ ์ž…๋ ฅ ์œ ํ˜•์€ ๋ฌด์‹œํ•˜๋„๋ก ScrollViewer๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<ScrollViewer IgnoredInputKind="MouseWheel,Pen"
              Width="500" Height="400"
              ContentOrientation="Both" >
    <SwapChainPanel x:Name="swapChainPanel" Width="40000" Height="40000">
        ...
    </SwapChainPanel>
</ScrollViewer>

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ ์Šคํฌ๋กค์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‚ฌ์šฉ์ž ์ง€์ •

๊ฐœ๋ฐœ์ž๋Š” Slider์˜ ValueChanged ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ๊ธฐ๋ณธ ์• ๋‹ˆ๋ฉ”์ด์…˜์˜ ์‚ฌ์šฉ์ž ์ง€์ • ๊ธฐ๊ฐ„์„ ์‚ฌ์šฉํ•˜์—ฌ ScrollViewer์˜ VerticalOffset์— ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

private void VerticalOffsetSlider_ValueChanged(
    object sender,
    RangeBaseValueChangedEventArgs e)
{
    double verticalOffsetDelta = GetOffsetDelta();
    TimeSpan animationDuration = GetCustomAnimationDuration();

    // Initiate the scroll and enqueue the ScrollInfo we'll use to identify related events
    ScrollInfo scrollInfo = _scrollViewer.ScrollBy(0.0, verticalOffsetDelta);
    _myScrollRequests.Add(new MyScrollRequest(scrollInfo, animationDuration));
}

// Listen to the ScrollViewer's ScrollAnimationStarting event and customize 
// the default animation
private void ScrollViewer_ScrollAnimationStarting(
    ScrollViewer scrollViewer,
    ScrollAnimationStartingEventArgs e)
{
    MyScrollRequest myScrollRequest = _myScrollRequests.FindRequest(e.ScrollInfo);
    e.Animation.Duration = myScrollRequest.AnimationDuration;
}

// Dequeue the ScrollInfo once the action completes
private void ScrollViewer_ScrollCompleted(
    ScrollViewer scrollViewer,
    ScrollCompletedEventArgs e)
{
    _myScrollRequests.RemoveRequest(e.ScrollInfo);
}

์„ธ๋ถ€ ๊ธฐ๋Šฅ ์„ค๊ณ„

์ค‘์š”ํ•œ ๋””์ž์ธ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜์‹ญ์‹œ์˜ค. ์—ฌ๊ธฐ์—๋Š” ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜ ์ด์ƒ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - API ์ œ์•ˆ(์ง€์›๋˜๋Š” ๋ชจ๋“  ์–ธ์–ด ๋˜๋Š” ์˜์‚ฌ ์ฝ”๋“œ๋Š” ๊ดœ์ฐฎ์Œ) - ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์œ„ํ•œ ๋””์ž์ธ ๋ชจํ˜• - ์ƒˆ UI์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ฑ ๊ทœ์ • ์ค€์ˆ˜์— ๋Œ€ํ•œ ์„ธ๋ถ€ ์ •๋ณด - ๊ธฐํƒ€ ๊ตฌํ˜„ ์ฐธ๊ณ  ์‚ฌํ•ญ

๋†’์€ ์ •์ฑ… ๋ฐ ๋‚ฎ์€ ์ •์ฑ… ์Šคํฌ๋กค

์Šคํฌ๋กค๋Ÿฌ(๋‚ฎ์€ ์ •์ฑ…)

Scroller๋Š” ๋ชจ๋“  ํ•„์ˆ˜ ์ด๋™ ๋ฐ ํ™•๋Œ€/์ถ•์†Œ ๋…ผ๋ฆฌ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํฌ๋กฌ์ด ์—†๋Š” ์ €์ˆ˜์ค€ ๋นŒ๋”ฉ ๋ธ”๋ก์ž…๋‹ˆ๋‹ค. ํ”Œ๋žซํผ์˜ ์ •์ฑ…์ด ํ›จ์”ฌ ๋” ๋‚ฎ์€ InteractionTracker ๋ฅผ XAML ํƒœ๊ทธ ์นœํ™”์ ์ธ ์š”์†Œ๋กœ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค.
๋ฌธ์ž ๊ทธ๋Œ€๋กœ Scroller๋Š” ScrollViewer์˜ "ํ‘œ์‹œ ์˜์—ญ"์ด๋ฉฐ ScrollContentPresenter๋ฅผ ๋Œ€์‹ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Scroller๋Š” ScrollContentPresenter์™€ ๋‹ฌ๋ฆฌ ๋‹จ์ˆœํžˆ ์ฝ˜ํ…์ธ ๋ฅผ ํด๋ฆฌํ•‘ํ•˜๋Š” ๊ฒƒ ์ด์ƒ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Scroller๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ๊ณผ ํ•จ๊ป˜ InteractionTracker๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • ์ ‘๊ทผ์„ฑ ์ง€์›
  • ๋งˆํฌ์—… ์นœํ™”์ ์ธ ๊ตฌ๋ฌธ ๋ฐ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด API
  • XAML์˜ ๋ ˆ์ด์•„์›ƒ ์‹œ์Šคํ…œ ๋ฐ ๊ฐ€์ƒํ™” ๊ธฐ๋Šฅ๊ณผ์˜ ํ†ตํ•ฉ

ScrollViewer(๋†’์€ ์ •์ฑ…)

์ƒˆ๋กœ์šด ScrollViewer๋Š” Scroller๋ฅผ ๋ž˜ํ•‘ํ•˜๊ณ  ํ•ด๋‹น ์†์„ฑ์„ ๊ณตํ†ต ๊ฐ’์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด <ScrollViewer/> ๋Š” ์ˆ˜ํ‰ ๋ฐ ์ˆ˜์ง ์Šคํฌ๋กค ์ƒํ˜ธ ์ž‘์šฉ์„ ๋ชจ๋‘ ์ง€์›ํ•˜๋„๋ก Scroller๋ฅผ ๊ตฌ์„ฑํ•˜์ง€๋งŒ ๊ธฐ๋ณธ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์ด ์ˆ˜์ง ์ „์šฉ ์Šคํฌ๋กค(์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ)๋กœ ๋‚˜ํƒ€๋‚˜๋„๋ก ์ฝ˜ํ…์ธ ์˜ ๋„ˆ๋น„๋ฅผ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

ScrollViewer๋Š” Scroller ์‚ฌ์šฉ์— ๋น„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • ๊ธฐ๋ณธ UX(์˜ˆ: ์Šคํฌ๋กค ํ‘œ์‹œ๊ธฐ, ๋งˆ์šฐ์Šค์šฉ ์˜์‹ ์Šคํฌ๋กค๋ฐ”, ๊ธฐ๋ณธ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ณก์„ )
  • Scroller/InteractionTracker(์˜ˆ: ํ‚ค๋ณด๋“œ ๋ฐ GamePad)์—์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š” UI ์Šค๋ ˆ๋“œ ๋ฐ”์šด๋“œ ์ž…๋ ฅ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์ง€์›
  • GamePad์˜ ๊ธฐ๋ณธ ํฌ์ปค์Šค ์ด๋™(ํŽ˜์ด์ง€ ์—…/๋‹ค์šด ๋ฐ ํŠธ๋ฆฌ๊ฑฐ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ์ž๋™์œผ๋กœ ํฌ์ปค์Šค ์„ค์ •)
  • ์‚ฌ์šฉ์ž ์‹œ์Šคํ…œ ์„ค์ •์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์ธ์‹(์˜ˆ: Windows์—์„œ ์ž๋™์œผ๋กœ ์Šคํฌ๋กค ๋ง‰๋Œ€ ์ˆจ๊ธฐ๊ธฐ)
  • (ํ–ฅํ›„) ์Šค๋ƒ… ํฌ์ธํŠธ๋ฅผ ์œ„ํ•œ ์†์‰ฌ์šด ๊ตฌ์„ฑ ์˜ต์…˜
  • (ํ–ฅํ›„) ๋” ๋งŽ์€ ๋งˆ์šฐ์Šค ํŒจ๋‹ ๋ชจ๋“œ ์ง€์›(์˜ˆ: ์—ด๊ธฐ/๋‹ซ๊ธฐ ์†์œผ๋กœ ์ฝ˜ํ…์ธ  ํด๋ฆญ ๋ฐ ๋“œ๋ž˜๊ทธ, ๋งˆ์šฐ์Šค ํœ ์„ ํ†ตํ•œ ๋งˆ์šฐ์Šค ํŒจ๋‹ / "๋‚˜์นจ๋ฐ˜" ์ปค์„œ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ฐ€์šด๋ฐ ๋ฒ„ํŠผ ํด๋ฆญ)

์–ด๋Š ๊ฒƒ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ธ๊ฐ€?

์•ฑ ๋ฐ ๋งŽ์€ ์ปจํŠธ๋กค ์ž‘์„ฑ์ž์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์„ ํƒ์€ ScrollViewer๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ”Œ๋žซํผ๊ณผ ์ผ์น˜ํ•˜๋Š” ๊ธฐ๋ณธ UX์™€ ๋” ํฐ ์‚ฌ์šฉ ํŽธ์˜์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Scroller๋Š” ๊ธฐ๋ณธ UX/์ •์ฑ…์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ํ–ฅ์ƒ๋œ FlipView ์ปจํŠธ๋กค ์ƒ์„ฑ ๋˜๋Š” ํฌ๋กฌ ์—†๋Š” ์Šคํฌ๋กค ํ‘œ๋ฉด ์ƒ์„ฑ).

ScrollViewer ์ „์šฉ API

HorizontalScrollBarVisibility / VerticalScrollBarVisibility

๊ฐ€๋กœ ๋ฐ ์„ธ๋กœ ์Šคํฌ๋กค ๋ง‰๋Œ€์˜ ๊ธฐ๋ณธ๊ฐ’์€ _Auto_์ž…๋‹ˆ๋‹ค. ์ฝ˜ํ…์ธ ๊ฐ€ ๋ทฐํฌํŠธ๋ณด๋‹ค ๋„“๊ฑฐ๋‚˜ ๋†’์€์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ํ‘œ์‹œ๋˜๊ฑฐ๋‚˜ ์ˆจ๊ฒจ์ง‘๋‹ˆ๋‹ค.

์ƒˆ ScrollViewer์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์—ด๊ฑฐํ˜• ์˜ต์…˜์—๋Š” '๋น„ํ™œ์„ฑํ™”๋จ' ์˜ต์…˜์ด ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ฐ€๋กœ ๋˜๋Š” ์„ธ๋กœ๋กœ ์ด๋™ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ƒํ˜ธ ์ž‘์šฉ์— ์‘๋‹ตํ•˜๋„๋ก ์ปจํŠธ๋กค์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์€ _HorizontalScrollMode_ ๋ฐ _VerticalScrollMode_ ์†์„ฑ์—๋งŒ ๊ธฐ๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค.

namespace Microsoft.UI.Xaml.Controls
{
    public enum ScrollBarVisibility
    {
        Auto = 0,    // Only visible when the ZoomFactor * content size > viewport
        Visible = 1, // Always visible
        Hidden = 2   // Always hidden
    }
}

์•„๋ž˜ ๊ทธ๋ฆผ์—์„œ ๋งˆ์šฐ์Šค ์ปค์„œ๋Š” ์ˆ˜์ง ์Šคํฌ๋กค ๋ง‰๋Œ€ ์œ„์— ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ˜ํ…์ธ ๊ฐ€ ๋ทฐํฌํŠธ์™€ ๋„ˆ๋น„๊ฐ€ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ๋ณผ ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฝ˜ํ…์ธ ๊ฐ€ ๋‘ ์ฐจ์› ๋ชจ๋‘์—์„œ ๋ทฐํฌํŠธ๋ณด๋‹ค ํฌ๋ฉด ์˜์‹ ์Šคํฌ๋กค ๋ง‰๋Œ€๊ฐ€ ๋ชจ๋‘ ํ‘œ์‹œ๋˜๊ณ  ์˜ค๋ฅธ์ชฝ ํ•˜๋‹จ ๋ชจ์„œ๋ฆฌ์— ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์Šคํฌ๋กค๋Ÿฌ ์ „์šฉ API

์ˆ˜ํ‰ ์Šคํฌ๋กค ์ปจํŠธ๋กค๋Ÿฌ / ์ˆ˜์ง ์Šคํฌ๋กค ์ปจํŠธ๋กค๋Ÿฌ

Scroller๋Š” _HorizontalScrollController_ ๋ฐ _VerticalScrollController_๋ฅผ _IScrollController_ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์œ ํ˜•์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ์Šคํฌ๋กค์„ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹๋Œ€ํ™”ํ˜• "์œ„์ ฏ"์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ScrollBars๋Š” ์ด๋Ÿฌํ•œ ์œ„์ ฏ์˜ ์นœ์ˆ™ํ•œ ์˜ˆ์ž…๋‹ˆ๋‹ค. ScrollViewer๋Š” Scroller์— ์ด๋Ÿฌํ•œ ๋‘ ๊ฐœ์˜ ์œ„์ ฏ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐœ๋ฐœ์ž๋Š” UI ์Šค๋ ˆ๋“œ ๋…๋ฆฝ ์ž…๋ ฅ์— ๋Œ€ํ•ด Composition.Visual์— ์˜์กดํ•˜๋Š” ์‚ฌ์šฉ์ž ์ง€์ • IScrollController ๊ตฌํ˜„์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

_scroller.HorizontalScrollController = new Acme.Slider(orientation: Orientation.Horizontal);
_scroller.VerticalScrollController = new Acme.Slider(orientation: Orientation.Vertical);

ScrollViewer / Scroller์˜ ํ•˜์œ„ ์ œํ•œ ์‚ฌํ•ญ

ํ”„๋ ˆ์ž„์›Œํฌ์—๋Š” Windows 10 2018๋…„ 4์›” ์—…๋ฐ์ดํŠธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์‚ฌ์šฉ์ž ์ง€์ • ์Šคํฌ๋กค ์ปจํŠธ๋กค์„ ๋นŒ๋“œํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ชจ๋“  ํ›„ํฌ๊ฐ€ ๋…ธ์ถœ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๋ฆด๋ฆฌ์Šค๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ œํ•œ ์‚ฌํ•ญ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
| ์ถœ์‹œ | ์ œํ•œ | ์ด์œ  |
|:-:|:--|:-:|
| Windows 10 Fall Creators ์—…๋ฐ์ดํŠธ(๋นŒ๋“œ 16299) ๋ฐ ์ด์ „ | ํฌ์ปค์Šค๋ฅผ ๋ฐ›์œผ๋ฉด ์š”์†Œ๊ฐ€ ์ž๋™์œผ๋กœ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. | UIElement์˜ BringIntoViewRequested ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. |
| | ์ปจํŠธ๋กค์€ EffectiveViewportChanged ์ด๋ฒคํŠธ์— ์ฐธ์—ฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ์—์„œ ๋ Œ๋”๋ง๋œ ํฌ์ปค์Šค ์‚ฌ๊ฐํ˜•์€ ๋ทฐํฌํŠธ์˜ ๊ฒฝ๊ณ„๋กœ ์ž˜๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. | UIElement์˜ RegisterAsScrollPort๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. |

์ œ์•ˆ๋œ API

์Šคํฌ๋กค ๋ทฐ์–ด

```C#
๊ณต๊ฐœ ํด๋ž˜์Šค Microsoft.UI.Xaml.Controls.ScrollViewer : ์ปจํŠธ๋กค
{
์Šคํฌ๋กค ๋ทฐ์–ด();

// Default Value: non-null instance
Windows.UI.Composition.CompositionPropertySet ExpressionAnimationSources { get; }

/*

  • ๋ ˆ์ด์•„์›ƒ ์ค‘์‹ฌ ์†์„ฑ
    */
    // ๊ธฐ๋ณธ๊ฐ’: null
    UIElement ์ฝ˜ํ…์ธ  { get; ์„ธํŠธ; };
// Default Value: Vertical
Microsoft.UI.Xaml.Controls.ContentOrientation ContentOrientation { get; set; };

// Default Value: 0.0
Double HorizontalOffset { get; };

// Default Value: 0.0
Double VerticalOffset { get; };

// Default Value: 1.0
Single ZoomFactor { get; };

// Default Value: 0.0
Double ExtentWidth { get; };

// Default Value: 0.0
Double ExtentHeight { get; };

// Default Value: 0.0
Double ViewportWidth { get; };

// Default Value: 0.0
Double ViewportHeight { get; };

// Default Value: 0.0
Double ScrollableWidth { get; };

// Default Value: 0.0
Double ScrollableHeight { get; };

// Default Value: Auto
M.UI.Xaml.Controls.ScrollBarVisibility HorizontalScrollBarVisibility {get;set;};

// Default Value: Auto
M.UI.Xaml.Controls.ScrollBarVisibility VerticalScrollBarVisibility {get;set;};

// Default Value: Collapsed
// Used for template binding the Visibility property of the horizontal
// ScrollBar in the control template
Visibility ComputedHorizontalScrollBarVisibility{ get; };

// Default Value: Collapsed
// Used for template binding the Visibility property of the vertical
// ScrollBar in the control template
Visibility ComputedVerticalScrollBarVisibility{ get; };

/*

  • ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ ์ค‘์‹ฌ ์†์„ฑ
    */
    // ๊ธฐ๋ณธ๊ฐ’: ์‚ฌ์šฉ
    Microsoft.UI.Xaml.Controls.ScrollMode HorizontalScrollMode { ๊ฐ€์ ธ์˜ค๊ธฐ; ์„ธํŠธ; };
// Default Value: Enabled
Microsoft.UI.Xaml.Controls.ScrollMode VerticalScrollMode { get; set; };

// Default Value: Disabled
Microsoft.UI.Xaml.Controls.ZoomMode ZoomMode { get; set; };

// Default Value: All
Microsoft.UI.Xaml.Controls.InputKind IgnoredInputKind { get; set; };

// Default Value: Idle
Microsoft.UI.Xaml.Controls.InteractionState State { get; };

// Default Value: Auto
Microsoft.UI.Xaml.Controls.ChainingMode HorizontalScrollChainingMode { get; set; };

// Default Value: Auto
Microsoft.UI.Xaml.Controls.ChainingMode VerticalScrollChainingMode { get; set; };

// Default Value: True
boolean IsHorizontalRailEnabled { get; set; };

// Default Value: True
boolean IsVerticalRailEnabled { get; set; };

// Default Value: Auto
Microsoft.UI.Xaml.Controls.ChainingMode ZoomChainingMode { get; set; };

// Default Value: None
M.UI.Xaml.Controls.SnapPointsType HorizontalSnapPointsType { get; set; };

// Default Value: None
M.UI.Xaml.Controls.SnapPointsType VerticalSnapPointsType { get; set; };

// Default Value: Near
M.UI.Xaml.C.Primitives.SnapPointsAlignment HorizontalSnapPointsAlignment { g;s; };

// Default Value: Near
M.UI.Xaml.C.Primitives.SnapPointsAlignment VerticalSnapPointsAlignment { g;s; };

// Default Value: 0.95, 0.95
Windows.Foundation.Numerics.Vector2 ScrollInertiaDecayRate { get; set; }; 

// Default Value: 0.95
Single ZoomInertiaDecayRate { get; set; }; 

// Default Value: 0.1
Double MinZoomFactor { get; set; };

// Default Value: 10.0
Double MaxZoomFactor { get; set; };

// Default Value: 0.0
Double HorizontalAnchorRatio { get; set; };

// Default Value: 0.0
Double VerticalAnchorRatio { get; set; };

// Forwarded to inner Scrollerโ€™s IScrollAnchorProvider implementation
// Default Value: null
Windows.UI.Xaml.UIElement CurrentAnchor { get; };

/*

  • ํ–‰๋™ ์–‘์‹
    */
    // ์ง€์ •๋œ ์˜คํ”„์…‹์œผ๋กœ ๋น„๋™๊ธฐ์‹์œผ๋กœ ์Šคํฌ๋กคํ•ฉ๋‹ˆ๋‹ค. ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ—ˆ์šฉ,
    // ์Šค๋ƒ… ํฌ์ธํŠธ๋ฅผ ์กด์ค‘ํ•ฉ๋‹ˆ๋‹ค. ScrollInfo ๊ตฌ์กฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    Microsoft.UI.Xaml.Controls.ScrollInfo ScrollTo(
    ์ด์ค‘ ์ˆ˜ํ‰ ์˜คํ”„์…‹,
    ์ด์ค‘ ์ˆ˜์ง ์˜คํ”„์…‹);
// Asynchronously scrolls to specified offsets with optional animation,
// with optional snap points respecting. Returns a ScrollInfo struct.
Microsoft.UI.Xaml.Controls.ScrollInfo ScrollTo(
    double horizontalOffset,
    double verticalOffset,
    Microsoft.UI.Xaml.Controls.ScrollOptions options);

// Asynchronously scrolls by the provided delta amount.
// Allows animation, respects snap points. Returns a ScrollInfo struct.
Microsoft.UI.Xaml.Controls.ScrollInfo ScrollBy(
    double horizontalOffsetDelta,
    double verticalOffsetDelta);

// Asynchronously scrolls by the provided delta amount with
// optional animation, with optional snap points respecting.
// Returns a ScrollInfo struct.
Microsoft.UI.Xaml.Controls.ScrollInfo ScrollBy(
    double horizontalOffsetDelta,
    double verticalOffsetDelta,
    Microsoft.UI.Xaml.Controls.ScrollOptions options);

// Asynchronously adds scrolling inertia. Returns a ScrollInfo struct.
Microsoft.UI.Xaml.Controls.ScrollInfo ScrollFrom(
    Vector2 offsetsVelocity,
    Nullable<Vector2> inertiaDecayRate);

// Asynchronously zooms to specified zoom factor. Allows animation
// (respects snap points in v2). Returns a ZoomInfo struct.
Microsoft.UI.Xaml.Controls.ZoomInfo ZoomTo(
    float zoomFactor,
    Nullable<Vector2> centerPoint);

// Asynchronously zooms to specified offsets with optional animation
// (with optional snap points respecting in v2). Returns a ZoomInfo struct.
Microsoft.UI.Xaml.Controls.ZoomInfo ZoomTo(
    float zoomFactor,
    Nullable<Vector2> centerPoint,
    Microsoft.UI.Xaml.Controls.ZoomOptions options);

// Asynchronously zooms by the provided delta amount. Allows animation
// (respects snap points in v2). Returns a ZoomInfo struct.
Microsoft.UI.Xaml.Controls.ZoomInfo ZoomBy(
    float zoomFactorDelta,
    Nullable<Vector2> centerPoint);

// Asynchronously zooms by the provided delta amount with optional animation
// (with optional snap points respecting in v2). Returns an ZoomInfo struct.
Microsoft.UI.Xaml.Controls.ZoomInfo ZoomBy(
    float zoomFactorDelta,
    Nullable<Vector2> centerPoint,
    Microsoft.UI.Xaml.Controls.ZoomOptions options);

// Asynchronously adds zooming inertia. Returns a ZoomInfo struct.
Microsoft.UI.Xaml.Controls.ZoomInfo ZoomFrom(
    float zoomFactorVelocity,
    Nullable<Vector2> centerPoint,
    Nullable<float> inertiaDecayRate);

/*

  • ๋‚ด๋ถ€ Scroller์˜ IScrollAnchorProvider ๊ตฌํ˜„์œผ๋กœ ์ „๋‹ฌ๋จ
    */
    ๋ฌดํšจ RegisterAnchorCandidate(UIElement ์š”์†Œ);
    ๋ฌดํšจ UnregisterAnchorCandidate(UIElement ์š”์†Œ);

/*

  • ์ด๋ฒคํŠธ
    */
    // HorizontalOffset, VerticalOffset ๋ฐ ZoomFactor ์ค‘ ํ•˜๋‚˜๊ฐ€ ์žˆ์„ ๋•Œ๋งˆ๋‹ค ๋ฐœ์ƒ
    // ์ข…์†์„ฑ ์†์„ฑ์ด ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
    ์ด๋ฒคํŠธ ์œ ํ˜• ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ณด๊ธฐ๋ณ€๊ฒฝ๋จ;
// Raised when any of the ExtentWidth and ExtentHeight dependency property changed.
event TypedEventHandler<ScrollViewer, Object> ExtentChanged;

// Raised when the State dependency property changed.
event TypedEventHandler<ScrollViewer, Object> StateChanged;

// Raised when a ScrollTo or ScrollBy call triggers an animation.
// Allows customization of that animation.
event TypedEventHandler<ScrollViewer, Microsoft.UI.Xaml.Controls.ScrollAnimationStartingEventArgs>
    ScrollAnimationStarting;

// Raised when a ZoomTo or ZoomBy call triggers an animation.
// Allows customization of that animation.
event TypedEventHandler
    <ScrollViewer, Microsoft.UI.Xaml.Controls.ZoomAnimationStartingEventArgs>
    ZoomAnimationStarting;

// Raised at the end of a ScrollTo, ScrollBy, or ScrollFrom asynchronous
// operation. Provides the original ScrollInfo struct.
event TypedEventHandler
    <ScrollViewer, Microsoft.UI.Xaml.Controls.ScrollCompletedEventArgs>
    ScrollCompleted;

// Raised at the end of a ZoomTo, ZoomBy, or ZoomFrom asynchronous operation.
// Provides the original ZoomInfo struct.
event TypedEventHandler
    <ScrollViewer, Microsoft.UI.Xaml.Controls.ZoomCompletedEventArgs>
    ZoomCompleted;

// Raised at the beginning of a bring-into-view-request participation.
// Allows customization of that participation. 
event TypedEventHandler
    <ScrollViewer, Microsoft.UI.Xaml.Controls.BringingIntoViewEventArgs>
    BringingIntoView;

// Raised to allow the listener to pick an anchor element, when anchoring
// is turned on.
event TypedEventHandler
    <ScrollViewer, Microsoft.UI.Xaml.Controls.AnchorRequestedEventArgs>
    AnchorRequested;

/*

  • ์ข…์†์„ฑ ์†์„ฑ
    */
    ์ •์  DependencyProperty ContentProperty { ๊ฐ€์ ธ์˜ค๊ธฐ; };
    ์ •์  DependencyProperty ContentOrientationProperty { ๊ฐ€์ ธ์˜ค๊ธฐ; };
    ์ •์  DependencyProperty ComputedHorizontalScrollBarVisibilityProperty { get; };
    ์ •์  DependencyProperty ComputedVerticalScrollBarVisibilityProperty { get; };
    ์ •์  DependencyProperty HorizontalScrollBarVisibilityProperty { get; };
    ์ •์  DependencyProperty VerticalScrollBarVisibilityProperty { get; };
static DependencyProperty IgnoredInputKindProperty { get; };
static DependencyProperty HorizontalScrollModeProperty { get; };
static DependencyProperty VerticalScrollModeProperty { get; };
static DependencyProperty ZoomModeProperty { get; };
static DependencyProperty HorizontalScrollChainingModeProperty {g};
static DependencyProperty VerticalScrollChainingModeProperty {g};
static DependencyProperty IsHorizontalRailEnabledProperty {g};
static DependencyProperty IsVerticalRailEnabledProperty {g};
static DependencyProperty ZoomChainingModeProperty { get; };
static DependencyProperty MinZoomFactorProperty { get; };
static DependencyProperty MaxZoomFactorProperty { get; };
static DependencyProperty HorizontalAnchorRatioProperty { get; };
static DependencyProperty VerticalAnchorRatioProperty { get; };

}
```

์—ด๋ฆฐ ์งˆ๋ฌธ

  • ๋ ˆ์ด์•„์›ƒ ์ œ์•ฝ ์กฐ๊ฑด์ด ์ฝ˜ํ…์ธ ์— ์ ์šฉ๋˜๋Š” ๋ฐฉ์‹์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ContentOrientation ์†์„ฑ(๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฆ„์˜ ์†์„ฑ)์ด ์žˆ์œผ๋ฉด ์ƒํ™ฉ์ด ๋” ๋ณต์žกํ•˜๊ฑฐ๋‚˜ ์‰ฌ์›Œ์ง‘๋‹ˆ๊นŒ?
  • ํ™•๋Œ€/์ถ•์†Œ ๊ด€๋ จ API๋ฅผ ํŒŒ์ƒ๋œ ์ปจํŠธ๋กค(์˜ˆ: ZoomViewer)๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ScrollViewer๊ฐ€ ์Šคํฌ๋กค์— ๋Œ€ํ•ด ์—„๊ฒฉํ•˜๊ฒŒ ์ ์šฉ๋˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?
Epic area-Scrolling feature proposal proposal-NewControl team-Controls

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ข‹์•„์š”. 3๊ฐ€์ง€ ์ƒํ™ฉ์„ ์—ผ๋‘์— ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

  1. ๋‚˜๋Š” ๋‚˜์˜ ํ˜„์žฌ ์œ„์น˜๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ƒ๊ด€ํ•˜์ง€ ์•Š๋Š”๋‹ค. ํŠน์ • ๋ชฉ์ ์ง€๋กœ ์Šคํฌ๋กค/ํ™•๋Œ€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
  2. ๋‚ด ํ˜„์žฌ ์œ„์น˜๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ด€์‹ฌ์ด ์žˆ์œผ๋ฉฐ ํ•ด๋‹น ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํŠน์ • ์–‘๋งŒํผ ์Šคํฌ๋กค/ํ™•๋Œ€/์ถ•์†Œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
  3. ๋‚˜๋Š” ์ตœ์ข… ๋ชฉ์ ์ง€๊ฐ€ ์–ด๋””์ธ์ง€ ์ƒ๊ด€ํ•˜์ง€ ์•Š๋Š”๋‹ค. ํ˜„์žฌ ์œ„์น˜์—์„œ ์Šคํฌ๋กค/ํ™•๋Œ€/์ถ•์†Œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

ํ›„์ž์˜ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๊ฒฝํ—˜์„ ํŒฌํ•˜๊ธฐ ์œ„ํ•ด ๋งˆ์šฐ์Šคํœ  ํด๋ฆญ๊ณผ ๊ฐ™์€ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ฆญํ–ˆ์„ ๋•Œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•œ ์ปค์„œ์˜ ์œ„์น˜์— ๋”ฐ๋ผ ํ˜„์žฌ ์œ„์น˜(๋ฌด์—‡์ด๋“  ๊ฐ„์—)์—์„œ ์ผ๋ถ€ ๊ด€์„ฑ์ด ์‚ฝ์ž…๋ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  61 ๋Œ“๊ธ€

์ œ ์ƒ๊ฐ์—๋Š” ์Šคํฌ๋กค์ด ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ ์™€ ํ™•๋Œ€/์ถ•์†Œ๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ ์˜ ํ•„์š”์„ฑ์€ ๋งค์šฐ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ฝ˜ํ…์ธ ๊ฐ€ ํ™•๋Œ€/์ถ•์†Œ๋˜๋ฉด ์Šคํฌ๋กคํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๋ณ„๋„์˜ ์ปจํŠธ๋กค์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๊ณ ๋ ค๊ฐ€ ์žˆ์—ˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋กค๋ง์—์„œ ํ™•์žฅ๋˜๋Š” ํ™•๋Œ€/์ถ•์†Œ ๊ฐ€๋Šฅํ•œ ์ปจํŠธ๋กค์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚ด ๊ด€์‹ฌ์‚ฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. 1) ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ํ•„์š”ํ•˜์ง€ ์•Š์€ ํ™•๋Œ€/์ถ•์†Œ ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ScrollViewer๊ฐ€ ์ง€๋‚˜์น˜๊ฒŒ ๋ณต์žกํ•ด์กŒ์Šต๋‹ˆ๋‹ค. 2) ScrollViewer๊ฐ€ ์ง€์›ํ•˜๋Š” ์ฝ˜ํ…์ธ  ํ™•๋Œ€ ์ปจํŠธ๋กค์„ ์ฐพ๋Š” ์‚ฌ๋žŒ์—๊ฒŒ๋Š” ๋ถ„๋ช…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


๋˜ํ•œ ์ œ์•ˆ ๋‚ด์—์„œ ์Šคํฌ๋กค ๋ทฐ์–ด ๋‚ด์—์„œ ํŠน์ • ์š”์†Œ๋กœ ์Šคํฌ๋กคํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด๋ก ์ ์œผ๋กœ ์ด๊ฒƒ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ทธ ์•ž์— ์žˆ๋Š” ๋ชจ๋“  ํ•ญ๋ชฉ์„ ์ธก์ •ํ•œ ๋‹ค์Œ ์ ์ ˆํ•œ ์˜คํ”„์…‹์œผ๋กœ ์Šคํฌ๋กคํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ฐ€์ƒํ™”๋œ ๋ชฉ๋ก์—์„œ๋Š” ์ˆ˜ํ–‰ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์œผ๋ฉฐ (๋‚ด ์ƒ๊ฐ์—) ๋งŽ์€ ์•ฑ( ๋ฐ ๊ฐœ๋ฐœ์ž)๋Š” ์ด๊ฒƒ์ด ๋‚ด์žฅ๋˜์–ด ํ˜œํƒ์„ ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
ํ•ญ๋ชฉ์ด "๋ชฉ๋ก"์— ์ถ”๊ฐ€๋˜๊ณ  ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•ญ๋ชฉ์ด ํ‘œ์‹œ๋˜๋„๋ก ํ•˜๋ ค๋Š” ์œ„์น˜๋ฅผ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค. ๋˜๋Š” ๋ชฉ๋ก ์•„๋ž˜์— ์žˆ๋Š” ์„ธ๋ถ€ ํ•ญ๋ชฉ์—์„œ ํŽ˜์ด์ง€๊ฐ€ ์—ด๋ฆฌ๋Š” ๋งˆ์Šคํ„ฐ/์„ธ๋ถ€ ์ •๋ณด ๋ณด๊ธฐ๊ฐ€ ์žˆ๋Š” ํŽ˜์ด์ง€๋ฅผ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค. ์ž์„ธํ•œ ๋‚ด์šฉ.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ์˜์—ญ ๋‚ด์˜ ๋‹ค๋ฅธ ํ•ญ๋ชฉ์ด ์‹œ๊ฐ์  ํŠธ๋ฆฌ์—์„œ ์ œ๊ฑฐ(๋˜๋Š” ์ถ”๊ฐ€)๋˜๋Š” ๋™์•ˆ ํ•ญ๋ชฉ์ด ๋ณด์ด๋Š” ์˜์—ญ์— ์œ ์ง€๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ๋„ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ด ๋ฌด์—‡์ธ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ๋ฐฑ๊ทธ๋ผ์šด๋“œ(๋˜๋Š” UI ์™ธ๋ถ€ ์Šค๋ ˆ๋“œ) ์ž‘์—…์ด ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ์˜์—ญ์— ๋‹ค๋ฅธ ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ์˜์—ญ ๋‚ด์—์„œ ์„ ํƒํ•œ ํ•ญ๋ชฉ์ด ์ด๋™ํ•  ๋•Œ ๋งค์šฐ ๋‚˜์ฉ๋‹ˆ๋‹ค.
ํ•ญ๋ชฉ์„ ํด๋ฆญ/ํƒญํ•  ๋•Œ ํ•ญ๋ชฉ์„ ์ด๋™ํ•˜๋ฉด ๋”์ฐํ•œ ์‚ฌ์šฉ ๊ฒฝํ—˜์ด ์ƒ๊น๋‹ˆ๋‹ค. ์ดˆ์ ์„ ๋งž์ถ”๊ฑฐ๋‚˜ ์„ ํƒํ•œ ํ•ญ๋ชฉ์ด ๊ฐ€์‹œ ์˜์—ญ ๋ฐ–์œผ๋กœ ์ด๋™ํ•˜๋ฉด ์ ‘๊ทผ์„ฑ ๋„๊ตฌ ๋ฐ ํ™”๋ฉด ํŒ๋…๊ธฐ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฃผ๋ณ€ ์‚ฌ๋žŒ๋“ค์ด ์ด๋™ํ•˜๋Š” ๋™์•ˆ(ํŠนํžˆ ํ•ด๋‹น ํ•ญ๋ชฉ์ด ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ญ์ œ๋œ ๊ฒฝ์šฐ) ๋™์ผํ•œ ์œ„์น˜์— ํ•ญ๋ชฉ์„ ์œ ์ง€ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์ž ์žฌ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์žˆ์ง€๋งŒ ์•„๋ฌด ๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@mrlacey ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ScrollViewer์™€ ์ด ์ œ์•ˆ์—์„œ ํ™•๋Œ€/์ถ•์†Œ ๊ธฐ๋Šฅ์ด ์–ผ๋งˆ๋‚˜ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด UWP ScrollViewer(์•„๋งˆ๋„ ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•?)์—์„œ ์ถœ๋ฐœํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ์ง€์ ์ด ๋  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ† ๋ก ์„ ์œ„ํ•œ ๊ณต๊ฐœ ์งˆ๋ฌธ์œผ๋กœ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€์ƒํ™”๋Š” ๋จผ์ € ํŠน์ • ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ ˆ์ด์•„์›ƒ ์‹œ์Šคํ…œ์„ ํ†ตํ•ด ์‹คํ–‰ํ•œ ๋‹ค์Œ ์Šคํฌ๋กคํ•  ์ˆ˜ ์žˆ๋Š” ์œ„์น˜๋ฅผ ํ™•๋ณดํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ผ์„ ๊นŒ๋‹ค๋กญ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๊ณผ๊ฑฐ์— ํŠน์ • ์ปจํŠธ๋กค(์˜ˆ: ListView)์— ์œ„์˜ ์ž‘์—…์„ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ์ž์ฒด ScrollIntoView ๋ฉ”์„œ๋“œ ๊ฐ€ ์žˆ์—ˆ๋˜ ์ด์œ ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋‹น์‹ ์ด ๊ตฌ์ƒํ•˜๊ณ  ์žˆ๋Š” ๋ฐฉ๋ฒ•์˜ ์œ ํ˜•์ž…๋‹ˆ๊นŒ? ๋˜๋Š” ๋ชจ๋“  UIElement์—๋Š” ํ•ญ๋ชฉ์œผ๋กœ ๋งค์šฐ ์‰ฝ๊ฒŒ ์Šคํฌ๋กคํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” StartBringIntoView ๋ฉ”์„œ๋“œ ๊ฐ€ ์žˆ์œผ๋ฉฐ ๋ทฐ๋กœ ๊ฐ€์ ธ์˜ฌ ๋•Œ ๋ทฐํฌํŠธ์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š”

Re: ๋‹ค๋ฅธ ๋‚ด์šฉ์ด ์ถ”๊ฐ€/์ œ๊ฑฐ๋˜๊ฑฐ๋‚˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ํ•ญ๋ชฉ์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹์œ ์ง€ํ•˜๋Š” ๊ฒƒ... ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์ง€ ์•Š๋‹ค๋Š” ๋ฐ ์ „์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ ์Šคํฌ๋กค ๊ณ ์ • ๊ธฐ๋Šฅ์ด ์กด์žฌํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. :) ๊ณผ๊ฑฐ์—๋Š” ListView/GridView์šฉ ๊ฐ€์ƒํ™” ํŒจ๋„์— ๋‚ด์žฅ๋˜์–ด ์žˆ๋˜ ๊ฑฐ์˜ ์•Œ๋ ค์ง€์ง€ ์•Š์€ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ตœ๊ทผ ๋ฆด๋ฆฌ์Šค์—์„œ ์šฐ๋ฆฌ๋Š” ์ด์™€ ๊ฐ™์€ ๊ฒƒ์„ ListView์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๊ณผ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ช…์‹œ์ ์ธ ๋…ธ๋ ฅ์„ ๊ธฐ์šธ์˜€์Šต๋‹ˆ๋‹ค.

ํ™•์žฅ๋œ ScrollViewer์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋ฅผ ํƒ์ƒ‰ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ Fluent Design ํŒ€์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ค์ •๋œ z ๊นŠ์ด ๊ฐ’์œผ๋กœ ์‹œ์ฐจ ๋ฐ ํ•ญ๋ชฉ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์กฐ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

XAML์ด MR ์•ฑ์˜ 3D ํ‘œํ˜„์œผ๋กœ ์ด๋™ํ•˜๊ณ  ๊นŠ์ด ๋ฐ ๊ทธ๋ฆผ์ž๊ฐ€ 2D XAML๋กœ ์ด๋™ํ•จ์— ๋”ฐ๋ผ - ์Šคํฌ๋กค์ด ๋‹ค๋ฅธ ๊นŠ์ด ๊ฐ’์˜ ํ•ญ๋ชฉ์„ ์ด๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•, ๊ทธ๋ฆผ์ž๊ฐ€ ์Šคํฌ๋กค ํ‘œ์‹œ๊ธฐ์˜ ์œ„ ๋˜๋Š” ๋’ค์— ๋ Œ๋”๋ง๋˜๋Š” ๋ฐฉ๋ฒ• ๋ฐ ์ž˜๋ฆด ์ˆ˜ ์žˆ๋Š” ๊ธฐํƒ€ ๋ฌธ์ œ XAML ํŒ€์˜ 3D ์‹คํ—˜์—์„œ - Windows UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ฒœ์ฒœํžˆ ์ƒˆ ๊ธฐ๋ณธ๊ฐ’์ด ๋จ์— ๋”ฐ๋ผ ์ƒˆ ๊ธฐ๋ณธ๊ฐ’์ด ๋  ์ˆ˜ ์žˆ๋Š” ํ•ญ๋ชฉ์— ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ œ ์ƒ๊ฐ์—๋Š” ์Šคํฌ๋กค์ด ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ ์™€ ํ™•๋Œ€/์ถ•์†Œ๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ ์˜ ํ•„์š”์„ฑ์€ ๋งค์šฐ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

์›น ๋ธŒ๋ผ์šฐ์ €, ๊ทธ๋ž˜ํ”ฝ ๋””์ž์ธ ์•ฑ, ์˜คํ”ผ์Šค ์•ฑ, PDF ๋ทฐ์–ด๋ฅผ ์ œ์™ธํ•˜๊ณ  ์ฝ˜ํ…์ธ  ๋ฌธ์„œ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ชจ๋“  ๊ฒƒ.

@mrlacey ์™€ ํ•จ๊ป˜ ํŠน์ • ์š”์†Œ๋ฅผ ๋ณด๊ธฐ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ๊ณผ ๋ณด๊ธฐ์—์„œ ํ‘œ์‹œ๋˜๋Š” ์œ„์น˜(์ƒ๋‹จ, ์ค‘์•™, ํ•˜๋‹จ ๋“ฑ...)๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์š”์†Œ๊ฐ€ ์™„์ „ํžˆ ๋ณด์ด๋Š”์ง€ ์ž˜๋ฆฌ๋Š”์ง€ ๊ฐ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์š”์†Œ๊ฐ€ ์ด๋ฏธ ์ „์ฒด ๋˜๋Š” ๋ถ€๋ถ„์ ์œผ๋กœ ๋ณด๊ธฐ์— ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ ์š”์†Œ๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ๋ณด๊ธฐ๋ฅผ ์Šคํฌ๋กคํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋ชจ๋‘ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์•ฑ์ด ๋งˆํฌ์—…์— ์„ค์ •ํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๋Š” ์†์„ฑ๊ณผ *ScrollMode ๋ฐ *ScrollBarVisibility ๋ฐ”๋กœ ๋’ค์— ZoomMode๊ฐ€ ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จํ•˜์—ฌ ์ผ๋ถ€ ์›๊ฒฉ ๋ถ„์„์„ ์ˆ˜์ง‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์•ฑ์€ ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ScrollMode ๋ฐ ScrollBarVisibility ์†์„ฑ์ด ์„ค์ •๋  ๋•Œ ๋‚ด๊ฐ€ ๊ด€์ฐฐํ•œ ๊ฒƒ์€ ์ฝ˜ํ…์ธ ์—์„œ ์ˆ˜ํ‰ ์Šคํฌ๋กค์„ ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ContentOrientation ์†์„ฑ์˜ ๋„์ž…์€ ์ด๋ฅผ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ€๋กœ ์Šคํฌ๋กค ํ›„ ๋‹ค์Œ์œผ๋กœ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ํ™•๋Œ€/์ถ•์†Œ์ž…๋‹ˆ๋‹ค.

ํ™•๋Œ€/์ถ•์†Œ์˜ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅ์„ฑ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ณ„๋„์˜(ํŒŒ์ƒ๋œ) ์ปจํŠธ๋กค์„ ๋„์ž…ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์˜ฌ๋ฐ”๋ฅธ ๋ฌธ์„œ/์ƒ˜ํ”Œ์ด ๋” ํšจ๊ณผ์ ์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋™์ž‘ ๋˜๋Š” ์ปจํ…์ŠคํŠธ ์—ด๊ฑฐํ˜•์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

ScrollViewer.ScrollBehaviour = ScrollBehaviour.Zoom;
ScrollViewer.ScrollBehaviour = ScrollBehaviour.Scroll;
ScrollViewer.ScrollBehaviour = ScrollBehaviour.ParallaxScroll;

ScrollViewer.ScrollBehaviour = ScrollBehaviour.Zoom; ๋Š” ๋งค์šฐ ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ZoomMode ๋Š” ๊ทธ๋Œ€๋กœ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

ScrollViewer.ScrollBehaviour = ScrollBehaviour.Zoom; ๋Š” ๋งค์šฐ ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ZoomMode ๋Š” ๊ทธ๋Œ€๋กœ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์Šคํฌ๋กค์ด ์•„๋‹Œ ํ™•๋Œ€/์ถ•์†Œ ์ฝ˜ํ…์ธ ์— ๋Œ€ํ•œ ํŒŒ์ƒ๋œ ์ปจํŠธ๋กค์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ์˜๊ฒฌ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ œ์•ˆ์„ ์‹œ์ž‘ํ•ด์•ผ ํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜์—๊ฒŒ๋Š” ํŠนํžˆ ํ„ฐ์น˜ ์žฅ์น˜์—์„œ ScrollViewer ๋‚ด์žฅ ์คŒ ๊ธฐ๋Šฅ์„ ๊ฐ–๋Š” ๊ฒƒ์ด ์‹ค์ œ๋กœ ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ UWP์˜ ์ด๋ฏธ์ง€/์ปจํŠธ๋กค์—์„œ ์ž์œ ํ˜• ์ด๋™/ํ™•๋Œ€/์ถ•์†Œ/ํšŒ์ „์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ์—†์œผ๋ฉฐ StackOverflow ๋ฐ GitHub์—์„œ ๋งŽ์€ ๊ด€๋ จ ์งˆ๋ฌธ์ด ์ œ๊ธฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ๋“œ๋ž˜๊ทธ ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ  ์ปจํŠธ๋กค ์ถ”๊ฐ€ ).

@micahl , ๋‚˜๋Š” ํ™•๋Œ€/์ถ•์†Œ๋กœ ๊ฐ€์ •ํ•˜๊ณ 

ํšŒ์ „ ์ œ์Šค์ฒ˜ ์ง€์›

์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๋ฏธ๋ž˜์— ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›๋ฉ๋‹ˆ๊นŒ?

๋‚˜์—๊ฒŒ๋Š” ํŠนํžˆ ํ„ฐ์น˜ ์žฅ์น˜์—์„œ ScrollViewer ๋‚ด์žฅ ์คŒ ๊ธฐ๋Šฅ์„ ๊ฐ–๋Š” ๊ฒƒ์ด ์‹ค์ œ๋กœ ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ UWP์˜ ์ด๋ฏธ์ง€/์ปจํŠธ๋กค์—์„œ ์ž์œ ํ˜• ์ด๋™/ํ™•๋Œ€/์ถ•์†Œ/ํšŒ์ „์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ์—†์œผ๋ฉฐ StackOverflow ๋ฐ GitHub์—์„œ ๋งŽ์€ ๊ด€๋ จ ์งˆ๋ฌธ์ด ์ œ๊ธฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ๋“œ๋ž˜๊ทธ ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ  ์ปจํŠธ๋กค ์ถ”๊ฐ€ ).

ํ™•๋Œ€/์ถ•์†Œ ๋ฐ ์Šคํฌ๋กค์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ œ์–ด๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ...

ScrollViewer.ScrollBehaviour = ScrollBehaviour.ZoomAndScroll;

๊ทธ๋Ÿฌ๋‚˜ ํ„ฐ์น˜ ์žฅ์น˜์—์„œ๋Š” ์†๊ฐ€๋ฝ์„ ๊ผฌ์ง‘๊ฑฐ๋‚˜ ๋ฏธ๋„๋Ÿฌ์ง€๋Š” ๊ฒƒ์ด ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ„ฐ์น˜ ์—†์ด ํ™•๋Œ€ํ•˜๋ ค๋ฉด [ + ] ๋ฐ [ ] ๋ฒ„ํŠผ์ด ๋‚˜ํƒ€๋‚˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š” ํ™•๋Œ€/์ถ•์†Œ ์ „์šฉ์ธ ๊ฒฝ์šฐ ์Šคํฌ๋กค ๋ง‰๋Œ€ ์ธ ๋“œ๋ž˜๊ทธ๊ฐ€ ํ™•๋Œ€ ๋ฐ ์ถ•์†Œ๋ฉ๋‹ˆ๋‹ค.

Microsoft Word UI๋ฅผ ๋ณด๋ฉด ์ƒํƒœ ํ‘œ์‹œ์ค„์— ํ™•๋Œ€/์ถ•์†Œ ์ปจํŠธ๋กค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฌธ์„œ ์˜์—ญ์˜ ์Šคํฌ๋กค๋ฐ”.

๋งˆ์šฐ์Šค ํ™•๋Œ€/์ถ•์†Œ ์ง€์›์ด ์ƒˆ๋กœ์šด ScrollViewer ์ปจํŠธ๋กค์— ๋‚ด์žฅ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๋”ฐ๋ผ์„œ ZoomMode๊ฐ€ ์ผœ์ ธ ์žˆ๊ฑฐ๋‚˜ ๋™์ž‘ ์†์„ฑ์—์„œ ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ํ—ˆ์šฉํ•˜๋ฉด ๋”ํ•˜๊ธฐ ๋ฐ ๋นผ๊ธฐ ๋ฒ„ํŠผ์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๊นŒ?

@JustinXinLiu ํšŒ์ „ ์ œ์Šค์ฒ˜๋ฅผ ์ง€์›ํ•˜๋ ค๋ฉด InteractionTracker(@likuba)์˜ ์ง€์›์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@mdtauk ์ƒˆ๋กœ์šด ScrollViewer๋Š” ๊ธฐ์กด ScrollViewer์™€ ์œ ์‚ฌํ•œ Ctrl + ๋งˆ์šฐ์Šคํœ ์„ ํ†ตํ•œ ๋งˆ์šฐ์Šคํœ  ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํ™•๋Œ€/์ถ•์†Œ๊ฐ€ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์„ ๋•Œ ์ปจํŠธ๋กค์— ๊ธฐ๋ณธ ํ”Œ๋Ÿฌ์Šค/๋งˆ์ด๋„ˆ์Šค ๋ฒ„ํŠผ์ด ์žˆ์–ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๊ฐ€ ๋ถˆ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ํ˜„์žฌ ์ธ์ƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ์ข…๋ฅ˜์˜ ์•ฑ(์˜ˆ: ์ฝ˜ํ…์ธ  ๋ฌธ์„œ ์•ฑ)์ด ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์œผ๋กœ ํ•ด๋‹น ๋ฒ„ํŠผ์„ ์•ฑ ๊ฒฝํ—˜์— ํ†ตํ•ฉํ•˜๋„๋ก ์„ ํƒํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์Šฌ๋ผ์ด๋”๋กœ ๊ตฌ๋ถ„๋œ ์ƒํƒœ ํ‘œ์‹œ์ค„์˜ - / +(์˜ˆ: Office) ๋˜๋Š” ๋‹ค๋ฅธ ๋ช…๋ น(์˜ˆ: ์ง€๋„) ์•„๋ž˜์— ์ˆ˜์ง์œผ๋กœ ๋‚˜ํƒ€๋‚˜๋Š” ๋‹จ์ˆœํ•œ -/+.

@micahl ์™œ ScrollFrom์ด ๊ทธ๋ ‡๊ฒŒ ๋ถˆ๋ฆฌ๋Š”์ง€ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ScrollBy์™€ ๋น„์Šทํ•˜์ง€๋งŒ ์†๋„ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@adrientetar ๋Š” ScrollFrom์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” ๋Œ€์‹  ๋‹ค๋ฅธ ๋งค๊ฐœ๋ณ€์ˆ˜ ์„ธํŠธ๋กœ ScrollBy์˜ ๋˜ ๋‹ค๋ฅธ ์˜ค๋ฒ„๋กœ๋“œ๊ฐ€ ์—†๋Š” ์ด์œ ๋ฅผ ๋ฌป๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๋„ค ๐Ÿ˜ƒ ํ•˜์ง€๋งŒ ScrollFrom ๋’ค์— ์žˆ๋Š” ๊ฐœ๋…์€ ์ฃผ์–ด์ง„ ์†๋„๋กœ ๋ฐฉํ–ฅ์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ƒ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์–ด์ง„ ์ง€์ ์œผ๋กœ ์ด๋™ํ•˜๋Š” ScrollBy์™€ ๋Œ€์กฐ๋ฉ๋‹ˆ๋‹ค.

์ข‹์•„์š”. 3๊ฐ€์ง€ ์ƒํ™ฉ์„ ์—ผ๋‘์— ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

  1. ๋‚˜๋Š” ๋‚˜์˜ ํ˜„์žฌ ์œ„์น˜๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ƒ๊ด€ํ•˜์ง€ ์•Š๋Š”๋‹ค. ํŠน์ • ๋ชฉ์ ์ง€๋กœ ์Šคํฌ๋กค/ํ™•๋Œ€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
  2. ๋‚ด ํ˜„์žฌ ์œ„์น˜๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ด€์‹ฌ์ด ์žˆ์œผ๋ฉฐ ํ•ด๋‹น ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํŠน์ • ์–‘๋งŒํผ ์Šคํฌ๋กค/ํ™•๋Œ€/์ถ•์†Œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
  3. ๋‚˜๋Š” ์ตœ์ข… ๋ชฉ์ ์ง€๊ฐ€ ์–ด๋””์ธ์ง€ ์ƒ๊ด€ํ•˜์ง€ ์•Š๋Š”๋‹ค. ํ˜„์žฌ ์œ„์น˜์—์„œ ์Šคํฌ๋กค/ํ™•๋Œ€/์ถ•์†Œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

ํ›„์ž์˜ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๊ฒฝํ—˜์„ ํŒฌํ•˜๊ธฐ ์œ„ํ•ด ๋งˆ์šฐ์Šคํœ  ํด๋ฆญ๊ณผ ๊ฐ™์€ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ฆญํ–ˆ์„ ๋•Œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•œ ์ปค์„œ์˜ ์œ„์น˜์— ๋”ฐ๋ผ ํ˜„์žฌ ์œ„์น˜(๋ฌด์—‡์ด๋“  ๊ฐ„์—)์—์„œ ์ผ๋ถ€ ๊ด€์„ฑ์ด ์‚ฝ์ž…๋ฉ๋‹ˆ๋‹ค.

๋•๋ถ„์— ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์ž์‹ ์˜ ๋งˆ์šฐ์Šค ํœ  ํด๋ฆญ ๊ฒฝํ—˜์„ ์œ„ํ•ด ScrollBy๋ฅผ ๋” ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ํŠน์ • ๊ฒฝ์šฐ์— ScrollFrom์ด ์œ ์šฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ScrollViewer ์ปจํŠธ๋กค์—์„œ๋Š” ViewportWidth ๋ฐ ViewportHeight ์†์„ฑ์— ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ˜„์žฌ ์ƒˆ ScrollViewer ์ปจํŠธ๋กค์—์„œ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๊ฑฐ ์ถ”๊ฐ€๋˜๋‚˜์š”?

@lhak , ๊ทธ ๊ฐ’์„ ๋ฌด์—‡์— ๋ฌถ๊ฒ ์Šต๋‹ˆ๊นŒ? ์ถ”๊ฐ€ํ•ด๋„ ํฐ ๋ณ€ํ™”๋Š” ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‹œ๋‚˜๋ฆฌ์˜ค์˜ ์ปจํ…์ŠคํŠธ์— ๋”ฐ๋ผ ๋ฐ”์ธ๋”ฉ๋ณด๋‹ค๋Š” ๊ถŒ์žฅํ•˜๋Š” ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ•˜๋‚˜์—์„œ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ์ด๋™ํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“œ๋Š” ์ฐจ์ด์ ์— ๋ฏผ๊ฐํ•˜๊ธฐ๋ฅผ ์›ํ•˜์ง€๋งŒ ๋” ๋‚˜์€ ๋Œ€์•ˆ์„ ํ™๋ณดํ•˜๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค.

@micahl ๋‚˜๋Š” ๊ณผ๊ฑฐ์— ์ผ๋ถ€ ๊ณ„์‚ฐ์—๋„ ํ•ด๋‹น ๊ฐ’์„ ์‚ฌ์šฉํ–ˆ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๊ทธ๋“ค์—๊ฒŒ ๋ฌถ์—ฌ ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@michael-hawker๋Š” ๋ถ„๋ช…ํžˆ ScrollViewer์—์„œ ์†์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ œ์•ˆ๋œ API์—์„œ๋Š” DependencyProperties๊ฐ€ ์•„๋‹Œ ์ผ๋ฐ˜ ์†์„ฑ์œผ๋กœ ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋™์ผํ•œ ๊ฐ’์€ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ปดํฌ์ง€์…˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž…๋ ฅ ๊ธฐ๋ฐ˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋นŒ๋“œํ•˜๋Š” ์ƒํ™ฉ์— ๋Œ€ํ•ด ExpressionAnimationSources ์†์„ฑ์˜ ์ผ๋ถ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋‚ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋‹ค์Œ๊ณผ ์œ ์‚ฌํ•œ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

<ScrollViewer x:Name="outputScrollViewer">
  <Viewbox MaxWidth="{x:Bind outputScrollViewer.ViewportWidth, Mode=OneWay}" MaxHeight="{x:Bind outputScrollViewer.ViewportHeight, Mode=OneWay}">
    <TheXamlElement Width=X Height=Y/>
  </Viewbox>
</ScrollViewer>

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐ€๋กœ ์„ธ๋กœ ๋น„์œจ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ๋‚ด๋ถ€ xaml ์š”์†Œ(๊ณ ์ • ํฌ๊ธฐ)๋ฅผ ์Šคํฌ๋กค/ํ™•๋Œ€/์ถ•์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์ž‘์€ xaml ์š”์†Œ๊ฐ€ ์Šคํฌ๋กค ๋ทฐ์–ด์˜ ๋ทฐํฌํŠธ๋ณด๋‹ค ๊ฒฐ์ฝ” ์ž‘์ง€ ์•Š๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ์ด๋ฏธ์ง€๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์‚ฌ์ง„ ์•ฑ๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

@lhak , ์ข‹์€ ์‹œ๋‚˜๋ฆฌ์˜ค! ์ด ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ํ˜„์žฌ ์ œ์•ˆ์— ์–ด๋–ป๊ฒŒ ์ˆ˜์šฉ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ํฐ ์†Œ๋ฆฌ๋กœ ์ƒ๊ฐํ•˜๋Š” ์ค‘... ContentOrientation ์†์„ฑ์— ๋‹ค๋ฅธ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค . ์ œ์•ˆ์„œ์˜ ํ˜„์žฌ ์˜ต์…˜:

  • ์—†์Œ = ์„ ํ˜ธํ•˜๋Š” ๋ฐฉํ–ฅ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฝ˜ํ…์ธ ์— ์–‘๋ฐฉํ–ฅ์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฌดํ•œ ํฌ๊ธฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์ˆ˜ํ‰ = ์ฝ˜ํ…์ธ ์— ์ˆ˜ํ‰์œผ๋กœ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฌดํ•œ ํฌ๊ธฐ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๋ ˆ์ด์•„์›ƒ ์ค‘์— ๋†’์ด๋ฅผ ๋ทฐํฌํŠธ๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.
  • ์ˆ˜์ง = ์ˆ˜ํ‰์˜ ์กฐ์˜ฎ๊น€

๋„ค ๋ฒˆ์งธ ์˜ต์…˜์€ ๋ ˆ์ด์•„์›ƒ ์ค‘ ๋†’์ด์™€ ๋„ˆ๋น„๋ฅผ ๋ทฐํฌํŠธ ํฌ๊ธฐ๋กœ ์ œํ•œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹น๋ถ„๊ฐ„์€ ์ด๊ฒƒ์„ "Viewport" ๋ฐฉํ–ฅ์ด๋ผ๊ณ  ๋ถ€๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ฆ„ ์ง€์ •์— ๋Œ€ํ•ด ์—‡๊ฐˆ๋ฆฐ ๋ฐ˜์‘์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์ ์–ด๋„ (๋” ์ผ๋ฐ˜์ ์ธ?) ์ด๋ฏธ์ง€์˜ ๊ฒฝ์šฐ ๋ ˆ์ด์•„์›ƒ ํ”„๋กœ์„ธ์Šค์˜ ์ผ๋ถ€๋กœ "์˜ฌ๋ฐ”๋ฅธ ๊ฒƒ"์ด ๋ฐœ์ƒํ•ด์•ผ ํ•˜๋ฏ€๋กœ Viewbox์™€ ๋ฐ”์ธ๋”ฉ์ด ๋ถˆํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

<ScrollViewer ContentOrientation="Viewport">
  <Image Stretch="Uniform" .../>
</ScrollViewer>

๋” ๋ณต์žกํ•œ ์ฝ˜ํ…์ธ ์˜ ๊ฒฝ์šฐ Viewbox์— ๋ž˜ํ•‘ํ•˜๊ณ  ๋ฐ”์ธ๋”ฉ์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<ScrollViewer ContentOrientation="Viewport">
  <Viewbox>
    <TheXamlElement Width=X Height=Y/>
  </Viewbox>
</ScrollViewer>

@micahl ๋˜ ๋‹ค๋ฅธ ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ๋” ๋น ๋ฅด๊ฒŒ(๋” ํฌ๊ฒŒ ์ฆ๊ฐ€) ๋งŒ๋“ค๊ณ  ์Šค๋ฌด๋”ฉ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด Scroller์˜ ๋งˆ์šฐ์Šค ํœ  ์ฒ˜๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ํœ  ์คŒ์„ ์กฐ์ •ํ•˜๋Š” API๊ฐ€์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋งˆ์šฐ์Šค ํœ  ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

๋งˆ์šฐ์Šค ํœ ์„ ์ˆ˜๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ปจํŠธ๋กค์ด ํ•˜๋Š” ์ผ์„ ๋‹ค์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ฐํ˜€์ง€๋ฉด ๋ถˆํ–‰ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹น์‹ ์ด ์ถ”๊ตฌํ•˜๋Š” ๊ฒƒ์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์š”์ง€๋Š” ZoomInertiaDecayRate๋ฅผ 1.0์— ๊ฐ€๊นŒ์šด ๊ฐ’์œผ๋กœ ์„ค์ •ํ•œ ๋‹ค์Œ ๋ฐ˜๋ณต๋˜๋Š” ํ™•๋Œ€/์ถ•์†Œ ์Šค๋ƒ… ์ง€์ ์„ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ZoomInertiaDecayRate ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ํ•„์ˆ˜ ์Šค๋ƒ… ํฌ์ธํŠธ์™€ ๊ด€๋ จ๋œ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ์‹œ๋„ํ•ด ๋ณผ ๋งŒํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜๋„ ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฉด IgnoredInputKind="Mousewheel"์„ ์„ค์ •ํ•œ ๋‹ค์Œ Scroller๋ฅผ ํ•˜์œ„ ๋ถ„๋ฅ˜ํ•˜์—ฌ OnPointerWheelChanged๋ฅผ ์žฌ์ •์˜ํ•˜๊ฑฐ๋‚˜ Scroller์˜ PointerWheelChanged ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@micahl ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋งˆ์šฐ์Šค ํœ  ๋™์ž‘์„ ๋ณด์ •ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ Adobe XD์™€ ๊ฐ™์€ ๋ฐฉ์‹์ด ๋งˆ์Œ์— ๋“ญ๋‹ˆ๋‹ค. ์•ฝ๊ฐ„์˜ ๊ฐ€์† ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ๋น ๋ฅด๊ณ  ์ถฉ๋ถ„ํžˆ ํ™•๋Œ€/์ถ•์†Œ ์ฆ๊ฐ€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กค๋Ÿฌ ๋งˆ์šฐ์Šค ํœ  ํ™•๋Œ€/์ถ•์†Œ ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ์•ฝ๊ฐ„ ๋Š๋ฆฌ๊ณ  ํ™•๋Œ€/์ถ•์†Œ ์ฆ๊ฐ€๊ฐ€ ์ •๋ง ์ž‘์Šต๋‹ˆ๋‹ค.

@adriantetar , ์ข‹์€ ํ”ผ๋“œ๋ฐฑ. ์กฐ์ •ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฆ๋ถ„ ๋ฐ ๊ฐ’์„ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹๋ชจ๋“  ์ข…๋ฅ˜์˜ ๋ณ€์ˆ˜ - ์žฌ์ •์˜ ๊ฐ€๋Šฅํ•œ ์†์„ฑ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ

์˜ค๋ฅธ์ชฝ. ์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ๊ฐ€ ์ง๋ฉดํ•œ ํ•œ ๊ฐ€์ง€ ๋ฌธ์ œ๋Š” Win10 ๋ฒ„์ „ 1809 ์ด์ƒ์—์„œ ์ปจํŠธ๋กค์ด ๋งˆ์šฐ์Šค ํœ  ์ž…๋ ฅ์„ ๊ธฐ๋ณธ InteractionTracker์— ์ „๋‹ฌํ•˜์—ฌ ๋ถ€๋“œ๋Ÿฌ์šด ๋™์ž‘์„ ์œ„ํ•ด UI ์Šค๋ ˆ๋“œ์—์„œ ์ฒ˜๋ฆฌ๋˜๋„๋ก ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์žฌ์ •์˜ ๊ฐ€๋Šฅํ•œ ์†์„ฑ์€ ๋จผ์ € ํ•˜์œ„ ์ˆ˜์ค€์—์„œ ๋…ธ์ถœ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 1809 ์ด์ „ ๋ฒ„์ „์˜ Win10์˜ ๊ฒฝ์šฐ UI ์Šค๋ ˆ๋“œ์—์„œ ์ œ์–ด ํ”„๋กœ์„ธ์Šค ๋งˆ์šฐ์Šค ํœ  ์ž…๋ ฅ์„ ํฌํ•จํ•˜๋Š” ๋…ผ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์žฌ์ •์˜ ๊ฐ€๋Šฅํ•œ ์†์„ฑ์„ ๋…ธ์ถœํ•˜๊ณ  ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ UI ์Šค๋ ˆ๋“œ์—์„œ ์ œ์–ด ํ”„๋กœ์„ธ์Šค ๋งˆ์šฐ์Šค ํœ ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋Œ€์ฒดํ•˜๋Š” ๋™์ž‘์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์†์„ฑ์ด ํ•˜์œ„ ์ˆ˜์ค€์— ์žˆ๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ์†์„ฑ์— ์˜์กดํ•˜๊ณ  ์ด๋ฅผ ํ•ฉ์„ฑ๊ธฐ๋กœ ๋˜๋Œ๋ฆฌ๋Š” ๊ฒƒ์œผ๋กœ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กค์€ ์•„๋งˆ๋„ ๋งˆ์šฐ์Šค ํœ ๋งŒํผ ๋ถ€๋“œ๋Ÿฝ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ๊ดœ์ฐฎ์„๊นŒ์š”?

๋”ฐ๋ผ์„œ ํ˜„์žฌ ํ™•๋Œ€/์ถ•์†Œ ๋™์ž‘์€ ์žฌ์ •์˜ํ•  ๋ฐฉ๋ฒ• ์—†์ด InteractionTracker์— ์ ์šฉ๋ฉ๋‹ˆ๊นŒ? ๊ทธ๋ฆฌ๊ณ  ์ด์ œ๋Š” ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ๊นจ๋œจ๋ฆด ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€๊ฒฝํ•  ๋ฐฉ๋ฒ•์ด ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค ๐Ÿค” cc @likuba

InteractionTracker์— ์—ฌ๊ธฐ์— ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜Š. ํŠนํžˆ, ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ์‚ฌ์šฉ์ž ์ •์˜๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” PointerWheelConfig ๋ฐ DeltaScaleModifier ์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๊ตฌ์ถ•ํ–ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋™๊ธฐํ™”ํ•˜๊ณ  ์ปจํŠธ๋กค ๋‚ด์—์„œ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋ฌธ์ œ/์œ„ํ—˜ ์—†์ด ์—ฌ๊ธฐ์—์„œ ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@micahl ๋‚ด๊ฐ€ ์ž‘์—…ํ•˜๊ณ  ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ํฅ๋ฏธ๋กœ์šด ์ƒํ™ฉ์ด ์žˆ๊ณ  PoC์— ๋Œ€ํ•œ ๋‚ด
10000x5000 ํฌ๊ธฐ์˜ ๊ฑฐ๋Œ€ํ•œ ์บ”๋ฒ„์Šค๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์บ”๋ฒ„์Šค ์ฃผ์œ„๋ฅผ ์ด๋™ํ•˜๋ ค๋ฉด ์Šคํฌ๋กค ๋ทฐ์–ด์— ์บก์Šํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์ด์ œ ์บ”๋ฒ„์Šค์— 2๊ฐœ์˜ InkCanvases(๋˜๋Š” ๊ทธ ์ด์ƒ)๊ฐ€ ์žˆ๊ณ  ๋‹ค๋ฅธ ์†๊ฐ€๋ฝ์œผ๋กœ ๋˜๋Š” 1๊ฐœ์˜ ์†๊ฐ€๋ฝ๊ณผ 1๊ฐœ์˜ ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ๋กœ ๋‘˜ ๋‹ค(๋˜๋Š” ๊ทธ ์ด์ƒ)์— ์“ฐ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด ์ปจํŠธ๋กค์„ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋–ป๊ฒŒ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ(๋˜๋Š” ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ)? :)
๋‚ด๊ฐ€ ๋ณธ ๊ธฐ๋ณธ ๋™์ž‘์€ ํ•˜๋‚˜์˜ InkCanvas์— ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ๊ฒƒ์„ ํ„ฐ์น˜ํ•˜์ž๋งˆ์ž ํŠน์ • InkCanvas๊ฐ€ "PointerLost"๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ทธ๊ฒŒ ์ „๋ถ€์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ•  ์ผ์ด ์—†์Šต๋‹ˆ๋‹ค.
๋ถ„๋ช…ํžˆ ๋‚ด scrollviewer๋Š” ๋‚ด๊ฐ€ ์ง์ ‘ ์ž‘์„ฑํ•œ ๊ฒƒ๊ณผ๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ๋ฉ‰๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๊ฒƒ์ด ์ด ์ปจํŠธ๋กค๋กœ ๊ฐ€๋Šฅํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค !

์•ˆ๋…•ํ•˜์„ธ์š” @stefangavrilasengage , ํฅ๋ฏธ๋กœ์šด ์‹œ๋‚˜๋ฆฌ์˜ค์ž…๋‹ˆ๋‹ค. :) PoC์—์„œ ์†๊ฐ€๋ฝ์ด InkCanvas์— ๋‚ด๋ ค๊ฐ„ ๋‹ค์Œ ์›€์ง์ด๊ธฐ ์‹œ์ž‘ํ•  ๋•Œ ์˜ˆ์ƒ๋˜๋Š” ๋™์ž‘์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ทธ๋ฆฌ๊ฑฐ๋‚˜ ํŒฌํ•ฉ๋‹ˆ๊นŒ?

์•ˆ๋…•ํ•˜์„ธ์š” @micahl - ๋‹ต์žฅํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ง€๊ธˆ์ฏค์ด๋ฉด ๋””์ง€ํ„ธ ํ™”์ดํŠธ๋ณด๋“œ ์•ฑ๊ณผ ๋น„์Šทํ•˜๋‹ค๊ณ  ์ง์ž‘ํ•˜์…จ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด์ œ ๋‚˜๋Š” ํ˜„์žฌ ์ผ์–ด๋‚˜๋Š” ์ผ์„ ์ œ์‹œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค:

  • ScrollViewer(๊ธฐ๋ณธ๊ฐ’): InkCanvas์—์„œ ํ•œ ์†๊ฐ€๋ฝ์œผ๋กœ ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์†๊ฐ€๋ฝ์€ ์ฒซ ๋ฒˆ์งธ InkCanvas๊ฐ€ ์ž…๋ ฅ์„ ์žƒ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ScrollViewerEx(์‚ฌ์šฉ์ž ์ •์˜ ์ปจํŠธ๋กค): ๋งŽ์€ ์†๊ฐ€๋ฝ๊ณผ InkCanvases๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ฆฌ๋ฉด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋„์›€์ด ๋˜๋‚˜์š”? :)
๊ณ ๋ง™์Šต๋‹ˆ๋‹ค !

@stefangavrilasengage ๋‹จ์ผ ํ„ฐ์น˜ ์ œ์Šค์ฒ˜๊ฐ€ ํŒฌ(ScrollViewer์˜ ๊ธฐ๋ณธ ๋™์ž‘)์ธ์ง€ ์ž‰ํฌ๋ฅผ ๊ทธ๋ฆฌ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ๋ฌป๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์—๋Š” ๋ณธ์งˆ์ ์ธ ๊ฐˆ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๊นŒ? ์ง€๋„์ฒ˜๋Ÿผ ์Šคํฌ๋กคํ•˜๋ ค๋ฉด ๋‘ ์†๊ฐ€๋ฝ์ด ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ? ํŽธ์ง‘ ๋ฒ„ํŠผ์„ ์‚ฌ์šฉํ•˜์—ฌ ํŽธ์ง‘ ๋ชจ๋“œ์— ๋“ค์–ด๊ฐ€๊ฑฐ๋‚˜ ๋‚˜๊ฐ€์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋“ฑ...

@micahl ๋‚ด ์‚ฌ๊ณผ - ๋‚ด๊ฐ€ ์–ด๋–ป๊ฒŒ ์ถฉ๋Œ์„ ํ•ด๊ฒฐํ–ˆ๋Š”์ง€ ์–ธ๊ธ‰ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์—ˆ์Šต๋‹ˆ๋‹ค.
์บ”๋ฒ„์Šค์— ์žˆ๋Š” ๊ฐœ์ฒด๋Š” Win2D ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์— ์ž‰ํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ๊ฐœ์ฒด์— ๋Œ€ํ•œ ํŽธ์ง‘ ๋ชจ๋“œ๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ํŽธ์ง‘์„ ์œ„ํ•ด InkCanvas๊ฐ€ ๋งจ ์œ„์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค(์‚ฌ์šฉ์ž ์ •์˜ ๊ฑด์กฐ ์‚ฌ์šฉ).
๋”ฐ๋ผ์„œ ๋‚ด ์ƒํ™ฉ์—์„œ(๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ์ ์šฉ๋˜๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Œ) InkCanvas์— "drawable"์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์œผ๋ฉด ์•„๋ฌด ๊ฒƒ๋„ ScrollViewer๋กœ ์ด๋™ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์ด๊ฒƒ์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌ ํ•ด์š” !

@micahl ๊ณผ ๋‚ด๊ฐ€ github ๋ฌธ์ œ์—์„œ ์„ž์ธ ๊ฒƒ์€ ์ด๋ฒˆ์ด ์ฒ˜์Œ์ด๋ผ๊ณ  ๋ฏฟ๊ธฐ

@micahl ๊ณผ ๋‚ด๊ฐ€ github ๋ฌธ์ œ์—์„œ ์„ž์ธ ๊ฒƒ์€ ์ด๋ฒˆ์ด ์ฒ˜์Œ์ด๋ผ๊ณ  ๋ฏฟ๊ธฐ

๋ฏธ์•ˆํ•ฉ๋‹ˆ๋‹ค ! ์ˆ˜์ •๋จ!

@micahgodbolt ๋งˆ์ง€๋ง‰์ด ์•„๋‹ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ;)
@stefangavrilasengage ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋‚ด ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋‹ต๋ณ€์ž…๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ InkCanvas ์ปจํŠธ๋กค์ด ํฌํ•จ๋œ Canvas์˜ ๋ถ€๋ชจ๋กœ Border์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ScrollViewer๋ฅผ ๊ต์ฒดํ•ด๋„ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ScrollViewer ๋‚ด์—์„œ ๋ฐœ์ƒํ•  ๋•Œ ๋‹ค์ค‘ ์ž…๋ ฅ/๋‹ค์ค‘ InkCanvas ๊ธฐ๋Šฅ์ด ๊ณ ์žฅ๋‚˜๋Š” ์›์ธ์ด ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€์ ์œผ๋กœ ์ผ๋ถ€ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์—ฐ๋ฝํ–ˆ์Šต๋‹ˆ๋‹ค.

@stefangavrilasengage , ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ํŒŒ์•…ํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„/์กฐ์‚ฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ œ์•ˆ๊ณผ ๋ณ„๋„๋กœ ์ถ”์ ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๊ทธ๊ฒƒ์— ๋Œ€ํ•œ ๋ฌธ์ œ๋ฅผ ์—ด โ€‹โ€‹๊ฒƒ์ธ๊ฐ€?

@micahl OnControlLoaded์—์„œ ๋‚ด ์ฝ˜ํ…์ธ ๋ฅผ ์Šคํฌ๋กคํ•˜๊ณ  ํ™•๋Œ€ํ•˜๋ฉด ์ž˜๋ชป๋œ ์œ„์น˜์— ์ด ์ฝ”๋“œ๋กœ .

์‚ฌ์šฉํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, @adriantetar! ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ œ์•ˆ์— ์ง‘์ค‘ํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค. ๋ณด๊ณ  ์žˆ๋Š” ๋‚ด์šฉ์— ๋Œ€ํ•ด ๋ณ„๋„์˜ ๋ฌธ์ œ๋ฅผ ์—ด โ€‹โ€‹์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํ•ด๋‹น ํ† ๋ก ์—์„œ ์–ป์€ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ์ œ์•ˆ์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ์ด ์ •๋‹นํ•œ์ง€ ๋…ผ์˜ํ•˜๊ธฐ ์œ„ํ•ด ์ด ์Šค๋ ˆ๋“œ๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@micahl ์™œ ExtentChanged/StateChanged/ViewChanged ์ด๋ฒคํŠธ์— ๊ฐ์ฒด๊ฐ€ ์ธ์ˆ˜๋กœ ํฌํ•จ๋˜๊ณ  State ๋ฉค๋ฒ„๊ฐ€ ์žˆ๋Š” StateChangedEventArgs๊ฐ€ ์•„๋‹Œ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? InteractionTracker๊ฐ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋œ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์—์„œ ์ œ์–ด ์†์„ฑ์„ ์ฟผ๋ฆฌํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ ํŒจํ„ด(์ธ์ˆ˜๊ฐ€ ์žˆ๋Š” ์ด๋ฒคํŠธ)์ด ์„ ํ˜ธ๋˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

https://github.com/XeorgeXeorge/Extended-Image-Viewer

ํฐ ๋ฌธ์ œ๋Š” ์•„๋‹ˆ์ง€๋งŒ ์ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์˜ ์ฒซ ๋ฒˆ์งธ ๋ถ€๋ถ„์€ ์ˆ˜ํ‰/์ˆ˜์ง ์Šคํฌ๋กค ๋ง‰๋Œ€๊ฐ€ ์ž ๊ฒจ(๋น„ํ™œ์„ฑํ™”)๋œ ๊ฒฝ์šฐ์—๋„ ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๋” ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด:
์— ๊ฐ•์ œ๋กœ ๋งž์ถ”๋ฉด์„œ ํ™•๋Œ€๋œ ์ฝ˜ํ…์ธ ๋ฅผ ํŒจ๋‹ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํšจ๊ณผ์ ์ธ ์ˆ˜์ง/์ˆ˜ํ‰ ๋ทฐํฌํŠธ.

์ด๊ฒƒ์„ ๊ฒŒ์‹œํ•  ๋•Œ ์‹ค์ œ๋กœ ๊ธฐ๋Šฅ์ ์ธ ํ™•๋Œ€/์ถ•์†Œ ์ž‘์—…์„ ์–ป์œผ๋ ค๋ฉด ScrollViewer์—์„œ HorizontalScrollbarVisibility ์†์„ฑ์„ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ํ•จ๊ป˜ ์Šคํฌ๋žฉํ•œ ์ด์ค‘ ์Šคํฌ๋กค ๋ทฐ์–ด ์†”๋ฃจ์…˜์œผ๋กœ ์ถฉ๋ถ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ถฉ๋ถ„ํ•œ.

@micahl ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์•„๋‹Œ ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ์ˆ˜ํ–‰ํ•  ๋•Œ Scroller๊ฐ€ StateChanged ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‚ด์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„
์ปจํŠธ๋กค์ด ๋„ˆ๋ฌด ํฌ๊ฒŒ ๋ž˜์Šคํ„ฐํ™”๋˜์ง€ ์•Š๋„๋ก https://github.com/microsoft/microsoft-ui-xaml/issues/541#issuecomment -488749469์—์„œ ์ œ์•ˆํ•œ ๋Œ€๋กœ Scroller๊ฐ€ ์œ ํœด ์ƒํƒœ๊ฐ€ ๋  ๋•Œ CanvasVirtualControl ํฌ๊ธฐ ์กฐ์ •์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ํ™•๋Œ€/์ถ•์†Œ ๋น„์œจ์„ ๊ธฐ์ค€์œผ๋กœ ํ•œ ์บ”๋ฒ„์Šค์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์•„๋‹Œ ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ™•๋Œ€/์ถ•์†Œ ๋ณ€๊ฒฝ์ด ์‹คํ˜„๋˜์ง€ ์•Š์•˜๋”๋ผ๋„ ZoomTo ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(afaict).

@adrientetar , ํ”„๋ ˆ์ž„์›Œํฌ์™€ ์•ฑ ๊ฐ„์— ์•ž๋’ค๋กœ ์ „๋‹ฌํ•  ์ด๋ฒคํŠธ ์ธ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ์•ฝ๊ฐ„์˜ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ arg๋Š” ๋ณด๋‚ธ ์‚ฌ๋žŒ์ด ๋…ธ์ถœํ•œ ์†์„ฑ์˜ ๋ณต์‚ฌ๋ณธ๋งŒ ์ œ๊ณตํ•˜๋ฏ€๋กœ ํ˜„์žฌ ๋””์ž์ธ์€ ์ด๋ฒคํŠธ arg๋ฅผ ๊ฐ–์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ, ํ˜„์žฌ ๋””์ž์ธ์€ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์•„๋‹Œ ํ™•๋Œ€/์ถ•์†Œ์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ํ˜ธ์ถœํ•˜๋ฉด StateChanged๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ZoomCompleted ๋ฐ ScrollCompleted ์ด๋ฒคํŠธ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. IIRC ์‚ฌ์šฉ์ž์˜ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•ด ํŠธ๋ฆฌ๊ฑฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. StateChanged์™€ ํ•จ๊ป˜ ๊ทธ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ViewChanged ์ด๋ฒคํŠธ๋Š” ๋ณด๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค(์‚ฌ์šฉ์ž ๋˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹). ์ด๋Š” ๋งค์šฐ ์„ฑ๋Šฅ์— ๋ฏผ๊ฐํ•œ ์ฝ”๋“œ ๊ฒฝ๋กœ๋ฅผ ๋งŒ๋“ค๊ณ  ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์—ฌ์ „ํžˆ ํ”ผ๋“œ๋ฐฑ์— ๊ท€๋ฅผ ๊ธฐ์šธ์ด๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šด ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”.

์˜ˆ, ํ˜„์žฌ ๋””์ž์ธ์€ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์•„๋‹Œ ํ™•๋Œ€/์ถ•์†Œ์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ํ˜ธ์ถœํ•˜๋ฉด StateChanged๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•„ ์•Œ์•˜์–ด, ์ด์ œ ์ดํ•ดํ–ˆ์–ด. ์ด๋ฒคํŠธ๊ฐ€ ํ•ญ์ƒ ๋ฐœ์ƒํ•˜๊ณ  SetFocus์™€ ๊ฐ™์€ ์›๋ณธ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๋ฐ ์•ฝ๊ฐ„์˜ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ZoomCompleted ๋ฐ ScrollCompleted ์ด๋ฒคํŠธ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. IIRC ์‚ฌ์šฉ์ž์˜ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•ด ํŠธ๋ฆฌ๊ฑฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ข‹์•„, ๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ ๊ฒฝ์šฐ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์ธ์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ZoomCompleted ๋ฐ StateChanged iff State == Idle์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด์ƒํ•˜์ง€ ์•Š์•„? ๋‚ด ๋ง์€, ๊ฐ™์€ ๊ฒƒ์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์€ ๋‹จ์ง€ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ด‰๋ฐœ๋˜์—ˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค ๐Ÿค”

@RBrid ์™€ ์ €๋Š” "์ „ํ™˜ ์ค‘"์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ๋„์ž…ํ•˜๊ณ  ์•ฝ๊ฐ„์˜ ์ด๋ฆ„์„ ๋‚˜๋ˆด ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๊ท€ํ•˜์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋” ์ ํ•ฉํ•œ์ง€ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

๋…ผ์˜๋œ ์•„์ด๋””์–ด๋Š” ์Šคํฌ๋กค/ํ™•๋Œ€/์ถ•์†Œ ์œ„์น˜์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ์ด ๊ณง ์„œ๋น„์Šค๋  ๋•Œ(์‚ฌ์šฉ์ž๊ฐ€ ์‹œ์ž‘ํ–ˆ๋“  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ๋“ ) StateChanged ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์ „ํ™˜ ์ค‘์œผ๋กœ ๋ณด๊ณ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ ์Šคํฌ๋กค(์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์•„๋‹˜)์˜ ์‹œํ€€์Šค ๋ชจ์–‘์ž…๋‹ˆ๋‹ค.

// ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ ์š”์ฒญ, ์• ๋‹ˆ๋ฉ”์ด์…˜
myScrollInfo = ScrollTo(100, ์• ๋‹ˆ๋ฉ”์ดํŠธ=true);
// ๋ช‡ ํ‹ฑ
StateChanged ๋ฐœ์ƒ(Scroller.State == ์ „ํ™˜ ์ค‘)
// ๋ช‡ ํ‹ฑ
StateChanged ๋ฐœ์ƒ(Scroller.State == ์• ๋‹ˆ๋ฉ”์ด์…˜)
// ๋งŽ์€ ํ‹ฑ
StateChanged ๋ฐœ์ƒ(Scroller.State == ์œ ํœด ์ƒํƒœ)

// ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ ์š”์ฒญ, ์• ๋‹ˆ๋ฉ”์ด์…˜ ์—†์Œ
myScrollInfo = ScrollTo(100, ์• ๋‹ˆ๋ฉ”์ดํŠธ=๊ฑฐ์ง“);
// ๋ช‡ ํ‹ฑ
StateChanged ๋ฐœ์ƒ(Scroller.State == ์ „ํ™˜ ์ค‘)
// ๋ช‡ ํ‹ฑ
StateChanged ๋ฐœ์ƒ(Scroller.State == ์œ ํœด ์ƒํƒœ)

InteractionState ์—ด๊ฑฐํ˜•์€ ์ƒํ˜ธ ์ž‘์šฉ ์ด์ƒ์˜ ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ๋•Œ๋ฌธ์— ScrollState์™€ ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ์ด๋ฆ„์„ ๋ฐ”๊พธ๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

enum ScrollState
{
    Idling = 0,
    Transitioning = 1,
    Interacting = 2,
    Inertial = 3,
    Animating = 4,
};

@micahl ๋„ค, ์ œ๊ฐ€ ์˜ˆ์ƒํ•œ ๊ฒƒ๊ณผ ๋งค์šฐ ํก์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋งŒ ์ฒ˜๋ฆฌํ•˜๋ ค๋Š” ์‚ฌ๋žŒ์€ Animating ์ƒํƒœ๋ฅผ ๊ฐ€๋กœ์ฑŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฆ„์˜ ๊ฒฝ์šฐ ์œ ํœด ์ƒํƒœ๊ฐ€ ์•„๋‹Œ ์œ ํœด ์ƒํƒœ๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค("์Šคํฌ๋กค๋Ÿฌ๊ฐ€ ์œ ํœด ์ƒํƒœ์ž…๋‹ˆ๋‹ค."/"์Šคํฌ๋กค์ด ์›€์ง์ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค."), ์ „ํ™˜ ์ค‘ โ†’ ๊ต๋ฐ˜ ์ค‘? (์ „ํ™˜์ด ๋งค์šฐ ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๋ชจ์…˜์ด ์‹œ์ž‘๋  ๋•Œ์ด๋ฏ€๋กœ ๊ต๋ฐ˜ ์ด ๋” ์ž˜ ์ž‘๋™ ํ•  ์ˆ˜ ์žˆ์Œ์„ ์ „๋‹ฌํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ), ๊ด€์„ฑ์€ ํ‘œ๋ฅ˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜› ํ•˜์ง€๋งŒ API ๊ฒ€ํ† ๋„ ํ•จ๊ป˜ ์ž‘๋™ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ €์–ด์ฃผ๋ฉด ์ฒ˜์Œ์—๋Š” ๋ธ”๋ Œ๋”ฉ์„ ์ƒ๊ฐํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. :) API ๊ฒ€ํ† ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ด๋ฆ„์„ ํ™•์ •ํ•˜๊ณ  ์„ ๋ก€๋ฅผ ์ฐพ๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์„ ๋•Œ ๊ฐ€์ค‘์น˜๋ฅผ ์ฃผ๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•ญ์ƒ ๋ช‡ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋Œ€์•ˆ์€ ์•Œ ์ˆ˜ ์—†์Œ ๋˜๋Š” ๋ณด๋ฅ˜ ์ค‘์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Idle๊ณผ ํ•จ๊ป˜ ๋‘ API ๋ชจ๋‘์— ๋Œ€ํ•œ ๊ธฐ์กด API์˜ ์„ ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, Idle์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฟจ์ฟจ. ๋ณด๋ฅ˜ ์ค‘์ธ sgtm, imo Unknown์€ Transitioning๋ณด๋‹ค ํ›จ์”ฌ ๋” ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

@micahl -- ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ ๋ฒˆํ˜ธ 3์—๋Š” ๋‹ค์Œ ํ•˜์œ„ ํ•ญ๋ชฉ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

ํšจ๊ณผ์ ์ธ ๋ทฐํฌํŠธ ๋ณ€๊ฒฝ์— ์ฐธ์—ฌ(ํ•„์ˆ˜)

ํ•ด๋‹น ํ•˜์œ„ ํฌ์ธํŠธ๋Š” ๊ธฐ์กด ์ด๋ฒคํŠธ FrameworkElement.EffectiveViewportChanged ํ•ฉ๋‹ˆ๋‹ค. ์ฝ˜ํ…์ธ ์˜ ๋น„๋™๊ธฐ ์ฃผ๋ฌธํ˜• ๋ถ€๋ถ„ ๋กœ๋“œ ๋„ ์š”๊ตฌ ์‚ฌํ•ญ/์šฐ์„  ์ˆœ์œ„๋ผ๊ณ  (๊ฐ„์ ‘์ ์œผ๋กœ) ๋งํ•  ์ˆ˜ ์žˆ๋Š” ํ•˜์œ„ ์š”์ ์ด ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด, MS Edge๊ฐ€ PDF ๋ฌธ์„œ(๋˜๋Š” SVG ๋˜๋Š” ๊ธฐํƒ€ ๋ณต์žกํ•œ ๋ฌธ์„œ)์˜ ํ™•๋Œ€๋œ ํŽ˜์ด์ง€๋ฅผ ํ‘œ์‹œํ•  ๋•Œ ScrollViewer๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ™•๋Œ€/์ถ•์†Œ๊ฐ€ 900%์ธ ๊ฒฝ์šฐ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์ด์œ ๋กœ ์ธํ•ด ์ „์ฒด PDF ํŽ˜์ด์ง€๋ฅผ 900% ํฌ๊ธฐ๋กœ ๋ฏธ๋ฆฌ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ์ด ๋ Œ๋”๋ง ์ž‘์—…(๋†’์€ ํ™•๋Œ€/์ถ•์†Œ ๋น„์œจ์—์„œ)์€ ๋ฌธ์„œ ๋ณต์žก์„ฑ(๋ฒกํ„ฐ ์š”์†Œ, ํšจ๊ณผ ๋“ฑ์˜ ์ˆ˜๋Ÿ‰), ๋ฌธ์„œ ํฌ๊ธฐ ๋ฐ ํ™•๋Œ€/์ถ•์†Œ ๋น„์œจ์— ๋”ฐ๋ผ ๋Œ€๋žต 3..20์ดˆ๊ฐ€ ์†Œ์š”๋ฉ๋‹ˆ๋‹ค. ์ด ์ง€์—ฐ์€ ์ตœ์ข… ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ›์•„๋“ค์ด๊ธฐ์—๋Š” ๋„ˆ๋ฌด ๊น๋‹ˆ๋‹ค.
  • ์ „์ฒด PDF ํŽ˜์ด์ง€์˜ ๋ Œ๋”๋ง๋œ ์ด๋ฏธ์ง€(๋น„ํŠธ๋งต)๋Š” ๋งค์šฐ ๋†’์€ DPI์—์„œ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ™•๋Œ€/์ถ•์†Œ ๋น„์œจ์ด ๋†’์„ ๋•Œ ์ˆ˜๋ฐฑ ๋ฉ”๊ฐ€๋ฐ”์ดํŠธ์˜ RAM์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

MS Edge๋Š” ํ™•๋Œ€๋œ PDF ํŽ˜์ด์ง€์˜ ์ผ๋ถ€๋ฅผ ์ฃผ๋ฌธํ˜•์œผ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ๋ถ€๋ถ„์„ ๋ณด๊ธฐ๋กœ ์Šคํฌ๋กคํ•  ๋•Œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ์ˆ ์€ ํŽ˜์ด์ง€๊ฐ€ ํ‘œ์‹œ๋˜๊ธฐ ์ „์— ๊ธด ์ง€์—ฐ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ ์š”๊ตฌ ์‚ฌํ•ญ์—์„œ ์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์–ธ๊ธ‰ํ•˜์ง€๋งŒ async Task ๋Œ€ํ•œ ๊ฐ„์ ‘์ ์ธ ์ง€์›๋„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ๋ Œ๋”๋ง๋˜์ง€ ์•Š์€(๋˜๋Š” ์ฆ‰์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š”) ๋ถ€๋ถ„์ด ๋ณด๊ธฐ๋กœ ์Šคํฌ๋กค๋˜๋ฉด ScrollViewer๋Š” ์ผ์‹œ์ ์œผ๋กœ ํ•ด๋‹น ๊ณต๊ฐ„์„ ๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•œ Brush ๋กœ ์ฑ„์šด ๋‹ค์Œ ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” async Task ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถ€ํ’ˆ์„ ๋ Œ๋”๋ง(๋˜๋Š” ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ฒ€์ƒ‰/๋กœ๋“œ)ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜์ค‘์— Task ์™„๋ฃŒ๋˜๋ฉด ๋ Œ๋”๋ง/๊ฒ€์ƒ‰/๋กœ๋“œ๋œ ๋ถ€๋ถ„์ด ScrollViewer์— ํ‘œ์‹œ๋˜์–ด Brush ์ž„์‹œ๋กœ ์ฑ„์›Œ์ง„ ๊ณต๊ฐ„์„ ๋ฎ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ๋†’์€ ์คŒ์—์„œ ๋†’์€ ๋ Œ๋”๋ง ๋น„์šฉ์— ๊ด€ํ•œ ๊ฒƒ๋งŒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์š”์ฒญ ์‹œ ๊ฒ€์ƒ‰๋˜๋Š” ์ฝ˜ํ…์ธ ์—๋„ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ScrollViewer์— ํ‘œ์‹œ๋œ ์ง€๋„ ๋˜๋Š” ์œ„์„ฑ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์ƒํ•ด ๋ณด์‹ญ์‹œ์˜ค. ์ง€๋„์˜ ์ผ๋ถ€๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๊ธฐ๋กœ ์Šคํฌ๋กคํ•  ๋•Œ๋งŒ ์„œ๋ฒ„์—์„œ ๋‹ค์šด๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค.

ํ™•๋Œ€/์ถ•์†Œ ๊ด€๋ จ API๋ฅผ ํŒŒ์ƒ๋œ ์ปจํŠธ๋กค(์˜ˆ: ZoomViewer)๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ScrollViewer๊ฐ€ ์Šคํฌ๋กค์— ๋Œ€ํ•ด ์—„๊ฒฉํ•˜๊ฒŒ ์ ์šฉ๋˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

ScrollViewer.ZoomFactor ์˜ ์ถ”๊ฐ€์— ๋Œ€ํ•ด ๋งค์šฐ ๊ฐ์‚ฌํ–ˆ์ง€๋งŒ ScrollViewer์— ์ง์ ‘ ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ๋ณด๊ณ  ๋†€๋ž์Šต๋‹ˆ๋‹ค. ์คŒ์„ ๋ณ„๋„์˜ ํด๋ž˜์Šค(๋ฐ˜๋“œ์‹œ ํŒŒ์ƒ ํด๋ž˜์Šค๋Š” ์•„๋‹˜)์— ๋„ฃ๋Š” ๊ฒƒ์ด ๋” ๊ฐ„๋‹จํ•˜๊ณ  ์•ˆ์ •์ ์ผ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์†Œ 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  1. ํด๋ž˜์Šค๋Š” ์•„๋งˆ๋„ ์ด๋ฆ„ ZoomViewer ํ•˜์ง€ ์ƒ์† ์•Š์Šต๋‹ˆ๋‹ค ScrollViewer ํ•˜์ง€๋งŒ, ์‚ฌ์šฉ ScrollViewer ์ž์‹ ์š”์†Œ๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ (๋…„ ControlTemplate ).
  2. ํด๋ž˜์Šค๋Š” ์•„๋งˆ๋„ ์ด๋ฆ„ ZoomableScrollViewer ์ƒ์† ์•Š์Šต๋‹ˆ๋‹ค ScrollViewer .
  3. ๋„ˆ๋ฌด ๋ณต์žกํ•˜๊ฑฐ๋‚˜ ์ง€์ €๋ถ„ํ•˜์ง€ ์•Š๋‹ค๋ฉด ScrollViewer ๋‚ด์—์„œ ์ง์ ‘ ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

17 ๋งˆ์šฐ์Šค ๊ฐ€์šด๋ฐ ํด๋ฆญ๊ณผ ์Šคํฌ๋กค์„ ์ง€์›ํ•˜๋Š” ๊ธฐ๋ณธ UX๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. (ํ•ด์•ผํ•œ๋‹ค)
18 ๋งˆ์šฐ์Šค๋ฅผ ํ†ตํ•œ ํด๋ฆญ ๋ฐ ์ด๋™ ๋ชจ๋“œ ์ง€์›(์˜ˆ: PDF ๋ทฐ์–ด ๋‚ด์—์„œ ์ฝ˜ํ…์ธ  ์ด๋™). (ํ•ด์•ผํ•œ๋‹ค)

18์ด 17๋ณด๋‹ค ํ›จ์”ฌ ์ž˜ ์ž‘๋™ํ•˜๊ณ  ์‹ค์ œ๋กœ 17์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์€ ๊ฑฐ์˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— 17์— ๋Œ€ํ•œ ์ง€์›์„ ์ œ๊ฑฐํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ณ ๋ คํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ ๋‚˜๋Š” โ€‹โ€‹17์ด ์˜๋„ํ•œ ์˜๋ฏธ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค(17์— ๋Œ€ํ•œ ์„ค๋ช…์€ ํ•œ ๋ฌธ์žฅ์— ๋ถˆ๊ณผํ•˜๋ฉฐ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์˜๋ฏธ๋ฅผ 100% ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค). 18์€ ๋งค์šฐ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ๋ฐ˜๋ฉด, 17์€ ๋ชจ๋‘๊ฐ€ ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ค์›Œ์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์–ด์ƒ‰ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ์˜ณ์ง€ ์•Š์Šต๋‹ˆ๊นŒ?
(์ด ๋ฌธ์ œ๋Š” ์ ‘๊ทผ์„ฑ์„ ์œ„ํ•ด 17์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ณ€๊ฒฝ๋˜์ง€๋งŒ ์ง€๊ธˆ๊นŒ์ง€ 17์ด ์ ‘๊ทผ์„ฑ ๋ฌธ์ œ๋ผ๊ณ  ๋งํ•˜๋Š” ์‚ฌ๋žŒ์„ ๋ณธ ์ ์ด ์—†์Šต๋‹ˆ๋‹ค.)

4 ์ž…๋ ฅ ๊ธฐ๋ฐ˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4๋ฒˆ์€ ์ ‘๊ทผ์„ฑ ๊ด€๋ จ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ScrollViewer(๋ฐ WinUI์˜ ๋‹ค๋ฅธ ๋ชจ๋“  ์ปจํŠธ๋กค)๊ฐ€ ์ ‘๊ทผ์„ฑ ์„ค์ •์„ ์กด์ค‘ํ•˜๋„๋ก ์š”์ฒญํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

Windows 10 -> ์‹œ์ž‘ -> ์„ค์ • -> ์ ‘๊ทผ์„ฑ -> ๋””์Šคํ”Œ๋ ˆ์ด -> Windows์—์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ‘œ์‹œ(์ผœ๊ธฐ ๋˜๋Š” ๋„๊ธฐ).

๋ถˆํ–‰ํžˆ๋„ ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ Microsoft ์•ฑ์ด Windows ์ ‘๊ทผ์„ฑ ์„ค์ •์„ ๋ฌด์‹œํ•˜๋Š” ๋งŽ์€ ์˜ˆ๋ฅผ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ๊บผ์ ธ ์žˆ์ง€๋งŒ Microsoft ์•ฑ์€ ์–ด์จŒ๋“  ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ด๋Ÿฌํ•œ ์ ‘๊ทผ์„ฑ ์„ค์ •์— ์˜์กดํ•˜๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์‹ค์งˆ์ ์ธ ์–ด๋ ค์›€์„ ์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์‚ฌ๋žŒ์ด ๋ถ€์ •์ ์ธ ๋ถ€์ž‘์šฉ ์—†์ด ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ฆ๊ธธ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋“ฑ์„ ๋ณด๋Š” ๋ฐ ์–ด๋ ค์›€์ด ์—†๋Š” ์‚ฌ์šฉ์ž๋Š” Windows์—์„œ ์ ‘๊ทผ์„ฑ ์„ค์ •์˜ ์ค‘์š”์„ฑ์„ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@verelpode ๋‹˜ , @predavid ๊ฐ€ ์ƒˆ๋กœ์šด ScrollViewer์— ๋Œ€ํ•œ ์ž‘์—…์„ ๊ฒƒ์ด๋ฏ€๋กœ ๊ทธ๋…€ ์—๊ฒŒ ๋งก๊ธฐ ๊ฒ ์Šต๋‹ˆ๋‹ค.

17 ๋งˆ์šฐ์Šค ๊ฐ€์šด๋ฐ ํด๋ฆญ๊ณผ ์Šคํฌ๋กค์„ ์ง€์›ํ•˜๋Š” ๊ธฐ๋ณธ UX๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. (ํ•ด์•ผํ•œ๋‹ค)
18 ๋งˆ์šฐ์Šค๋ฅผ ํ†ตํ•œ ํด๋ฆญ ๋ฐ ์ด๋™ ๋ชจ๋“œ ์ง€์›(์˜ˆ: PDF ๋ทฐ์–ด ๋‚ด์—์„œ ์ฝ˜ํ…์ธ  ์ด๋™). (ํ•ด์•ผํ•œ๋‹ค)

18์ด 17๋ณด๋‹ค ํ›จ์”ฌ ์ž˜ ์ž‘๋™ํ•˜๊ณ  ์‹ค์ œ๋กœ 17์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์€ ๊ฑฐ์˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— 17์— ๋Œ€ํ•œ ์ง€์›์„ ์ œ๊ฑฐํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ณ ๋ คํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ ๋‚˜๋Š” โ€‹โ€‹17์ด ์˜๋„ํ•œ ์˜๋ฏธ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค(17์— ๋Œ€ํ•œ ์„ค๋ช…์€ ํ•œ ๋ฌธ์žฅ์— ๋ถˆ๊ณผํ•˜๋ฉฐ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์˜๋ฏธ๋ฅผ 100% ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค). 18์€ ๋งค์šฐ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ๋ฐ˜๋ฉด, 17์€ ๋ชจ๋‘๊ฐ€ ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ค์›Œ์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์–ด์ƒ‰ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ์˜ณ์ง€ ์•Š์Šต๋‹ˆ๊นŒ?
(์ด ๋ฌธ์ œ๋Š” ์ ‘๊ทผ์„ฑ์„ ์œ„ํ•ด 17์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ณ€๊ฒฝ๋˜์ง€๋งŒ ์ง€๊ธˆ๊นŒ์ง€ 17์ด ์ ‘๊ทผ์„ฑ ๋ฌธ์ œ๋ผ๊ณ  ๋งํ•˜๋Š” ์‚ฌ๋žŒ์„ ๋ณธ ์ ์ด ์—†์Šต๋‹ˆ๋‹ค.)

@verelpode 17์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉฐ 18์ด 17๋ณด๋‹ค ๋” ์ค‘์š”ํ•˜๊ณ  ์ผ๋ฐ˜์ ์œผ๋กœ ๋” ์ง๊ด€์ ์ด๋ผ๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ "์™ผ์ชฝ ํด๋ฆญ ๋ฐ ๋Œ๊ธฐ"๊ฐ€ ์„ ํƒ ๋˜๋Š” ๋Œ์–ด์„œ ๋†“๊ธฐ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ชฉ์ ์œผ๋กœ ์ด๋ฏธ ์‚ฌ์šฉ๋˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. . ์ด๋Ÿฌํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์˜ ๊ฒฝ์šฐ ์•ฑ์ด ๊ฐ€์šด๋ฐ ํด๋ฆญ(17)์„ ํ†ตํ•ด ์Šคํฌ๋กค์„ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ €๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ๋•Œ๋•Œ๋กœ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ค‘๊ฐ„ ํด๋ฆญ ์Šคํฌ๋กค์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์™ผ์ชฝ ํด๋ฆญ + ๋“œ๋ž˜๊ทธ๋Š” ํ…์ŠคํŠธ ์„ ํƒ ๋˜๋Š” ์ด๋ฏธ์ง€์˜ ๋“œ๋ž˜๊ทธ + ๋“œ๋กญ์„ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค. UWP ๋ธŒ๋ผ์šฐ์ €์—๋Š” 18๊ฐœ๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋˜๊ณ  17๊ฐœ๊ฐ€ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ๋ณ„๋„์˜ ์†์„ฑ์„ ํ†ตํ•ด ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@lukasf

์ €๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ๋•Œ๋•Œ๋กœ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ค‘๊ฐ„ ํด๋ฆญ ์Šคํฌ๋กค์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์™ผ์ชฝ ํด๋ฆญ + ๋“œ๋ž˜๊ทธ๋Š” ํ…์ŠคํŠธ ์„ ํƒ ๋˜๋Š” ์ด๋ฏธ์ง€์˜ ๋“œ๋ž˜๊ทธ + ๋“œ๋กญ์„ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

์ข‹์€ ์ ์€ ํ…์ŠคํŠธ ์„ ํƒ ๋“ฑ์ด ์ž‘๋™์„ ๋ฉˆ์ถ”๊ฒŒ ํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฐ€๋Šฅํ•œ ์†”๋ฃจ์…˜์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ? ์–ด์ƒ‰ํ•œ 17 ๋ชจ๋“œ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋Œ€์‹  ๋งˆ์šฐ์Šค ๊ฐ€์šด๋ฐ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ๋งˆ์šฐ์Šค ๊ธฐ๋ฐ˜ ํŒจ๋‹ ๋ชจ๋“œ(18)๋ฅผ ์‹œ์ž‘ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์•ฑ์ด ํ•˜๋Š” ์ผ์„ ๋ณผ ๋•Œ ์ผ๋ถ€ ์•ฑ์—์„œ๋Š” ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ  ์˜์—ญ์„ ๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์œผ๋กœ ํด๋ฆญํ•˜๋Š” ๋™์•ˆ ์ŠคํŽ˜์ด์Šค๋ฐ” ํ‚ค๋ฅผ ๋ˆ„๋ฅธ ์ƒํƒœ์—์„œ ๋งˆ์šฐ์Šค ๊ธฐ๋ฐ˜ ํŒจ๋‹์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์†”๋ฃจ์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ํŒจ๋‹ ๋ชจ๋“œ๊ฐ€ ์ŠคํŽ˜์ด์Šค๋ฐ”+ํด๋ฆญ์„ ํ†ตํ•ด์„œ๋งŒ ์‹œ์ž‘๋˜๊ธฐ ๋•Œ๋ฌธ์— ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ  ์˜์—ญ ๋‚ด์—์„œ ์™ผ์ชฝ ํด๋ฆญ์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ŠคํŽ˜์ด์Šค๋ฐ”+ํด๋ฆญ์„ ํ†ตํ•œ ํŒจ๋‹์€ ๋งค์šฐ ํŽธ์•ˆํ•˜๊ณ  ํŽธ๋ฆฌํ•˜๊ณ  ๋น ๋ฆ…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด ์ŠคํŽ˜์ด์Šค๋ฐ”+ํด๋ฆญ ์†”๋ฃจ์…˜์€ ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ  ์˜์—ญ ๋‚ด์— ํŽธ์ง‘ ๊ฐ€๋Šฅํ•œ ํ…์ŠคํŠธ ์ƒ์ž๋ฅผ ํ‘œ์‹œํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ์•ฑ์—์„œ ๊ตฌํ˜„ํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ์ฝ˜ํ…์ธ  ์˜์—ญ์— ํŽธ์ง‘ ๊ฐ€๋Šฅํ•œ ํ…์ŠคํŠธ ์ƒ์ž๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ํŒจ๋‹ ๊ธฐ๋Šฅ์œผ๋กœ ์ธํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ํ…์ŠคํŠธ ์ƒ์ž์— ๊ณต๋ฐฑ์„ ์ž…๋ ฅํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ง์”€ํ•˜์‹  ๋Œ€๋กœ ์ด ๊ธฐ๋Šฅ์€ ์†์„ฑ์„ ํ†ตํ•ด ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š” ์ŠคํŽ˜์ด์Šค๋ฐ”๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ง๊ณ  ๋งˆ์šฐ์Šค ๊ฐ€์šด๋ฐ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ๋งˆ์šฐ์Šค ๊ธฐ๋ฐ˜ ํŒจ๋‹ ๋ชจ๋“œ(18)๋ฅผ ์‹œ์ž‘ํ•˜๋„๋ก ํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ํ…์ŠคํŠธ ์ƒ์ž์— ๊ณต๋ฐฑ์„ ์ž…๋ ฅํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๊ฐ€ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

@verelpode
๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €์™€ ๋ชจ๋“œ 17์„ ์ง€์›ํ•˜๋Š” ๋งŽ์€ ๋‹ค๋ฅธ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ(Word, Adobe Reader, Outlook ๋“ฑ)์„ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ์ „ํžˆ ์ด๊ฒƒ์ด ๊ตฌํ˜„๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ๊ฐœ์ธ์ ์œผ๋กœ ์–ด์ƒ‰ํ•˜๋‹ค๊ณ  ๋Š๋‚€๋‹ค๊ณ  ํ•ด์„œ ๊ทธ๊ฒƒ์ด ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์œ ์šฉํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๋‘ ๋ชจ๋“œ ๋ชจ๋‘ ์˜ตํŠธ์ธํ•ด์•ผ ํ•˜๋ฉฐ ๊ฐœ๋ฐœ์ž๋Š” ์•ฑ์—์„œ ์‚ฌ์šฉํ•  ํ•ญ๋ชฉ์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์•ฑ์— ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ŠคํŽ˜์ด์Šค๋ฐ”+ํด๋ฆญ ๋™์ž‘๋„ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค.

@lukasf -- ์ข‹์•„์š”, ์ข‹์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํŒจ๋‹ ๋ชจ๋“œ(18)๊ฐ€ ํ…์ŠคํŠธ ์„ ํƒ ๋˜๋Š” ์ด๋ฏธ์ง€์˜ ๋“œ๋ž˜๊ทธ+๋“œ๋กญ ๋“ฑ์„ ๋ฐฉ์ง€ํ•˜์ง€ ๋ชปํ•œ๋‹ค๋ฉด ๋ชจ๋“œ 17 ์‚ฌ์šฉ์„ ์ค‘์ง€ํ•˜๊ณ  18๋กœ ์ „ํ™˜ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ์ด์ œ ๋‘ ๋ชจ๋“œ ๋ชจ๋‘์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์„ค์ •์ด ์‹ค์ œ๋กœ ์ง€์›๋ฉ๋‹ˆ๋‹ค.

@verelpode ๋ฐ @lukasf ํ”ผ๋“œ๋ฐฑ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๊ถ๊ทน์ ์œผ๋กœ Scroller ์ปจํŠธ๋กค์˜ ๊ณต๊ฐœ ๋…ธ๋ธŒ๊ฐ€ 17๋ฒˆ๊ณผ 18๋ฒˆ์„ ์ผœ๊ณ  ๋Œ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋Š” ์ ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. 17=๋งˆ์šฐ์Šค ๊ธฐ๋ฐ˜ ์ผ์ • ์†๋„ ํŒจ๋‹ ๋ฐ 18=๋งˆ์šฐ์Šค ๊ธฐ๋ฐ˜ ํŒจ๋‹.

๋ฐฉ๊ธˆ ๋‚ด๊ฐ€ ํ•œ ์กฐ์‚ฌ ์ž‘์—…์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด PR https://github.com/microsoft/microsoft-ui-xaml/pull/1472 ๋ฅผ ๋ณด๋ƒˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜์˜ Scroller๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 17๊ณผ 18์„ ๋ชจ๋‘ ์ง€์›ํ•˜๋Š” ๋ฐ ์–ผ๋งˆ๋‚˜ ๊ทผ์ ‘ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ณด๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

์†”๋ฃจ์…˜์€ ํ„ฐ์น˜ ๊ธฐ๋ฐ˜ ๋˜๋Š” ๋งˆ์šฐ์Šค ํœ  ๊ธฐ๋ฐ˜ ํ™˜๊ฒฝ๊ณผ ๋‹ฌ๋ฆฌ 100% UI ์Šค๋ ˆ๋“œ ๊ธฐ๋ฐ˜์ด์ง€๋งŒ 18=๋งˆ์šฐ์Šค ๊ธฐ๋ฐ˜ ํŒจ๋‹์—์„œ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ์ž˜ ์ง„ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์šฐ์Šค์˜ PointerMoved ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๋Š” ๋™์•ˆ ScrollTo ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ถ๊ทน์ ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ๊ธฐ๋ณธ InteractionTracker ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์†๊ฐ€๋ฝ ์›€์ง์ž„๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋งˆ์šฐ์Šค ์›€์ง์ž„์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

17=๋งˆ์šฐ์Šค ๊ธฐ๋ฐ˜ ์ผ์ • ์†๋„ ํŒจ๋‹(๋‚ด๊ฐ€ ๊ฐœ์ธ์ ์œผ๋กœ ์‹ซ์–ดํ•˜๋Š” ๊ฒฝํ—˜)์˜ ๊ฒฝ์šฐ ์ƒํ™ฉ์ด ํ›จ์”ฌ ๋” ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค. ํ”„๋กœํ† ํƒ€์ž…์€ ์ด์ƒ์ ์ด์ง€ ์•Š์œผ๋ฉฐ ๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ํ•˜์ง€๋Š” ์•Š์•˜์ง€๋งŒ ํŠนํžˆ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€๊ฐ€ ๊ด€๋ จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ผ์ •ํ•œ ์†๋„ ํŒจ๋‹(์ฆ‰, 0-์†๋„ ๊ฐ์‡  ํŒจ๋‹) ์ค‘์— ํ˜„์žฌ Scroller๊ฐ€ ์ด์ „ ์œ„์น˜๋กœ ์ ํ”„ํ•˜์ง€ ์•Š๊ณ  ์ด๋™์„ ์ค‘์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(ScrollBy(0, 0) ์‚ฌ์šฉ) . ์ปดํฌ์ง€์…˜ ์Šค๋ ˆ๋“œ๊ฐ€ UI ์Šค๋ ˆ๋“œ๋ณด๋‹ค ์–ผ๋งˆ๋‚˜ ์•ž์„œ ๊ฐ”๋Š”์ง€ ์•„๋Š” ๊ฒƒ์€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฒฐํ•จ์ด ์—†๋Š” ๋ฐฉ์‹์œผ๋กœ ์†๋„๋ฅผ ์ค‘์ง€ํ•˜๋ ค๋ฉด ๋ช‡ ๊ฐ€์ง€ ์ƒˆ๋กœ์šด ๊ณต๊ฐœ Scroller API๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ๋งˆ์šฐ์Šค์˜ PointerReleased ์ด๋ฒคํŠธ ํ›„์— ๋งˆ์šฐ์Šค ์บก์ฒ˜๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๋‹ฌ์„ฑํ•˜๋ ค๋ฉด ์ƒˆ๋กœ์šด Xaml ํ”„๋ ˆ์ž„์›Œํฌ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    ์–ด์จŒ๋“  ์ด๊ฒƒ์€ ๊ธฐ๋ณธ InteractionTracker๊ฐ€ ์ผ๋ถ€ ๊ฒฝํ—˜์„ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๊ฒฝ์šฐ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ํ–ฅํ›„ Scroller/InteractionTracker ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•  ๋•Œ ์ด๋Ÿฌํ•œ ์ ์„ ํ™•์‹คํžˆ ์—ผ๋‘์— ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค.

@RBrid

์ƒํ™ฉ์€ 18=๋งˆ์šฐ์Šค ๊ธฐ๋ฐ˜ ํŒจ๋‹์— ๋Œ€ํ•ด ๊ฝค ์ž˜ ์ง„ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
17=๋งˆ์šฐ์Šค ๊ธฐ๋ฐ˜ ์ผ์ • ์†๋„ ํŒจ๋‹(๋‚ด๊ฐ€ ๊ฐœ์ธ์ ์œผ๋กœ ์‹ซ์–ดํ•˜๋Š” ๊ฒฝํ—˜)์˜ ๊ฒฝ์šฐ ์ƒํ™ฉ์ด ํ›จ์”ฌ ๋” ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค.

ํฅ๋ฏธ๋กœ์šด ๊ฒฐ๊ณผ! ์ด ๊ฒฝ์šฐ 17=constant-velocity์˜ ์–ด๋ ค์›€์„ ๊ณ ๋ คํ•˜๊ณ  18์ด ์™ผ์ชฝ ํด๋ฆญ์˜ ์ •์ƒ์ ์ธ ์‚ฌ์šฉ์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ๊ณ ๋ คํ•˜๋ฉด ์ œ ๊ฐœ์ธ์ ์ธ ์˜๊ฒฌ์œผ๋กœ๋Š” ์ œ์•ˆ์ด ๋‹ค์Œ์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  17์„ ํฌ๊ธฐํ•˜๊ณ  18์„ ์ง€์›ํ•˜์ง€๋งŒ 17=constant-velocity๊ฐ€ ํฌ๊ธฐ๋˜๋ฉด ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋ถˆํ‰ํ• ์ง€ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์กฐ์‚ฌ์— ๋Œ€ํ•ด @RBrid ์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋ชจ๋“œ 18์ด ์ด๋ฏธ ์ž‘๋™ํ•œ๋‹ค๋Š” ์†Œ์‹์„ ๋“ฃ๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค! UI ์Šค๋ ˆ๋“œ ๋กœ๋“œ ์ค‘์—๋„ ์›ํ™œํ•œ ์ž‘๋™์„ ํ—ˆ์šฉํ•˜๋ ค๋ฉด InteractionTracker์—์„œ ์ด์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

@verelpode ๋‘ ๋ชจ๋“œ ๋ชจ๋‘ "Should"๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“œ 17์„ ์‹คํ˜„ํ•˜๊ธฐ์—๋Š” ๋…ธ๋ ฅ์ด ๋„ˆ๋ฌด ๋งŽ์€ ๊ฒฝ์šฐ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋‚˜์ค‘์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Œ). ๊ทธ๋Ÿฌ๋‚˜ ๋ˆ„๊ตฐ๊ฐ€๋Š” ๋„ˆ๋ฌด ๋งŽ์€ ๋ณ€๊ฒฝ ์—†์ด ๊ทธ๊ฒƒ์„ ์‹คํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ScrollViewer์— "Ctrl" ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰