WPF ์—ฐ๊ตฌ์†Œ

๊ทธ๊ฐ„์˜ WPF ์˜คํ”ˆ์†Œ์Šค, ๋ฐ‹์—…, ๊ต์œก, ์ฑ…, ์œ ํŠœ๋ธŒ ํŠœํ† ๋ฆฌ์–ผ ๋“ฑ์„ ํ†ตํ•ด ๊ณต์œ ํ–ˆ๋˜ ๋‚ด์šฉ๋“ค์„ ๋‹ค์‹œ ํ•œ ๋ฒˆ ๋ฆฌ๋ทฐํ•˜๊ณ  ์ •๋ณด๋“ค์„ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•œ ๊ณต๊ฐ„์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋žœ ์‹œ๊ฐ„ ์ˆœ์œผ๋กœ ๊ณผ๊ฑฐ ๋‚ด์šฉ๋“ค์„ ๊ฐ€์ ธ์™€ ์žฌ๊ตฌ์„ฑํ•˜๊ณ  ๋ณด์™„ํ•˜๋Š” ์‹์œผ๋กœ ์ง„ํ–‰๋  ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

์ž‘์„ฑ๋œ ๋ชฉ๋ก


  • 2023.02.11 - 1ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก :heavy_check_mark:
  • 2023.02.18 - 2ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.02.25 - 3ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.03.04 - 4ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.03.18 - 5ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.03.23 - 1ํšŒ WPF ๋ฐ‹์—… (with Infragistics)
  • 2023.03.25 - 6ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.04.01 - 7ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.04.08 - 8ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.04.27 - 2ํšŒ WPF ๋ฐ‹์—… (with Infragistics)
  • 2023.04.29 - 9ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.05.06 - 10ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.05.13 - 11ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.05.18 - .NET L!VE 2023 Spring (์•„๋ฐœ๋กœ๋‹ˆ์•„)
  • 2023.05.20 - 12ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.05.24 - 3ํšŒ WPF ๋ฐ‹์—… (with Infragistics)
  • 2023.06.22 - 4ํšŒ WPF ๋ฐ‹์—… (with Infragistics)
  • 2023.07.27 - 5ํšŒ WPF ๋ฐ‹์—… (with Infragistics)
  • 2023.08.24 - 6ํšŒ WPF ๋ฐ‹์—… (with Infragistics)
  • 2023.08.26 - 13ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.09.02 - 14ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.09.09 - 15ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.09.16 - 16ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก
  • 2023.09.26 - 7ํšŒ WPF ๋ฐ‹์—… (with Infragistics)
  • 2023.10.26 - 8ํšŒ WPF ๋ฐ‹์—… (with Infragistics)
  • 2023.11.23 -.NET Conf 2023 @ Blazor Korea (WPF for Blazor)
  • 2023.12.21 - 9ํšŒ WPF ๋ฐ‹์—… (with Infragistics)
  • 2024.01.25 - 10ํšŒ WPF ๋ฐ‹์—… (with Infragistics)
  • 2024.03.28 - 11ํšŒ WPF ๋ฐ‹์—… (with Infragistics & Microsoft)
6 Likes

1ํšŒ WPF ์Šคํ„ฐ๋”” ๊ต์œก - ์˜คํ”„๋ผ์ธ (์ด์žฌ์›…)

2023.02.11์ผ ํ† ์š”์ผ 13:00~17:00 (4์‹œ๊ฐ„)


๊ต์œก ๋‚ด์šฉ์€ WPF ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด WPF์˜ ์ฃผ์š” ๊ธฐ์ˆ ๋“ค์„ ๋นŒ๋“œ์—… ํ•ด๊ฐ€๋ฉฐ ๋ฆฌ๋ทฐํ•ด ๊ฐ€๋Š” ๊ณผ์ •์ด์—ˆ์Šต๋‹ˆ๋‹ค.

  1. Project v
  2. Application v
  3. Window v
  4. StackPanel v
  5. Grid v
  6. Border v
  7. DataContext v
  8. Button v
  9. Property v
  10. Style v
  11. Template
  12. ControlTemplate
  13. ContententTemplate
  14. DataTemplate
  15. Binding
  16. Trigger
  17. IValueConverter
  18. CustomControl
  19. Themes
  20. Generic

1. Project


WPFํ”„๋กœ์ ํŠธ๋Š” ๋‹ท๋„ท ํ”„๋ ˆ์ž„์›Œํฌ ๋˜๋Š” ์ฝ”์–ด ์„ ํƒ์— ๋”ฐ๋ผ ๊ตฌ์กฐ์™€ ๊ตฌ์„ฑ์ด ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๊ฒฝ์šฐ์—๋Š” ์œˆ๋„์šฐ์— ์„ค์น˜๋œ ํ”„๋ ˆ์ž„์›Œํฌ DLL ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด WPF๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์ฝ”์–ด์˜ ๊ฒฝ์šฐ์—๋Š” ํ”„๋กœ์ ํŠธ ์†์„ฑ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

<TargetFramework>net8.0-windows</TargetFramework>
<UseWPF>True</UseWPF>

๊ทธ๋ฆฌ๊ณ  ์•„๋ฌด๋ฆฌ ์ฝ”์–ด๋ผ ํ• ์ง€๋ผ๋„ WPF๋Š” ์œˆ๋„์šฐ์—์„œ๋งŒ ๋™์ž‘์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋“œ์‹œ TargetFramework์—์„œ -windows ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ์กฐ ๋ฐฉ์‹๊ณผ ์ฝ”์–ด ์ „ํ™˜

๋‹ท๋„ท ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋‹ท๋„ท ์ฝ”์–ด์˜ ์ฐธ์กฐ ๋ฐฉ์‹์€ WPF ํ”„๋กœ์ ํŠธ์˜ ๊ตฌ์กฐ์™€ ๊ตฌ์„ฑ์— ํฐ ์ฐจ์ด๋ฅผ ๋ณด์ž…๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ์‹œ์Šคํ…œ์— ์„ค์น˜๋œ DLL์„ ์ง์ ‘ ์ฐธ์กฐํ•˜๋Š” ๋ฐ˜๋ฉด, ์ฝ”์–ด๋Š” NuGet ํŒจํ‚ค์ง€๋ฅผ ํ†ตํ•œ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ฐจ์ด๋Š” ํ”„๋กœ์ ํŠธ์˜ ์„ค์ •, ๋ฐฐํฌ ๋ฐ ์œ ์ง€ ๊ด€๋ฆฌ์— ์ค‘๋Œ€ํ•œ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

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

ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ ์‚ฌํ•ญ๊ณผ ํ™˜๊ฒฝ์„ ๋ฉด๋ฐ€ํžˆ ๊ฒ€ํ† ํ•˜์—ฌ, ์ฝ”์–ด ๊ธฐ๋ฐ˜์œผ๋กœ์˜ ์ „ํ™˜ ๊ฐ€๋Šฅ์„ฑ์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค, ์ด๋Š” ๊ธฐ์ˆ ์ ์ธ ๋ฐœ์ „๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์žฅ๊ธฐ์ ์ธ ํ”„๋กœ์ ํŠธ ์œ ์ง€ ๊ด€๋ฆฌ ์ธก๋ฉด์—์„œ๋„ ์ด์ต์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฐ์ •์€ ํŒ€์˜ ๊ธฐ์ˆ  ์—ญ๋Ÿ‰๊ณผ ํ”„๋กœ์ ํŠธ์˜ ํŠน์ • ์š”๊ตฌ ์‚ฌํ•ญ(๋ ˆ๊ฑฐ์‹œ ๋“ฑ)์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋ชจ๋“  ์‚ฌํ•ญ๋“ค์„ ํ™•์ธํ•œ ํ›„์— ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

2. Application


Application ํด๋ž˜์Šค๋Š” ์ „๋ฐ˜์ ์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜๋ช… ์ฃผ๊ธฐ ๊ด€๋ฆฌ ๋ฐ ์ „์—ญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜๋ช… ์ฃผ๊ธฐ ๊ด€๋ฆฌ: WPF Application ํด๋ž˜์Šค๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‹œ์ž‘๊ณผ ์ข…๋ฃŒ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ์ดˆ๊ธฐ WPF ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ๋ณธ ๊ตฌ์„ฑ์ธ App.xaml ํŒŒ์ผ์˜ Application ์ธ์Šคํ„ด์Šค๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰๊ณผ ํ•จ๊ป˜ ๋‚ด๋ถ€์ ์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Application์„ ์ง์ ‘ ๋งค๋‰ด์–ผ๋กœ ๊ตฌ์„ฑํ•  ๊ฒฝ์šฐ ํ”„๋กœ๊ทธ๋žจ ์‹œ์ž‘์ ์—์„œ Application์„ ์ง์ ‘ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ฐ Run ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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

  • ๋ฉ”์ธ ์œˆ๋„์šฐ ์„ค์ • ๋ฐ ์‹คํ–‰: Application ํด๋ž˜์Šค๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฉ”์ธ ์œˆ๋„์šฐ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์‹คํ–‰ํ•  ์ฑ…์ž„์ด ์žˆ์Šต๋‹ˆ๋‹ค. MainWindow ์†์„ฑ์„ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ฃผ ์œˆ๋„์šฐ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, Run() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ง€์ •๋œ ์œˆ๋„์šฐ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” OnStartup ์ด๋ฒคํŠธ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ์ปค์Šคํ…€ ๋กœ์ง์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. MainWindow ์†์„ฑ์„ ์ง์ ‘ ํ• ๋‹นํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, Run() ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์˜ํ•ด ์ž๋™์œผ๋กœ ์ฒซ ๋ฒˆ์งธ ์ƒ์„ฑ๋œ ์œˆ๋„์šฐ๊ฐ€ MainWindow์œผ๋กœ ์ง€์ •๋ฉ๋‹ˆ๋‹ค.

  • ์ข…๋ฃŒ ์กฐ๊ฑด ์„ค์ •: ShutdownMode ์†์„ฑ์„ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ข…๋ฃŒ ์กฐ๊ฑด์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ShutdownMode.OnMainWindowClose ์˜ต์…˜์„ ์„ ํƒํ•˜๋ฉด ๋ฉ”์ธ ์œˆ๋„์šฐ๊ฐ€ ๋‹ซํž ๋•Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋„ ์ž๋™์œผ๋กœ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์˜ต์…˜์œผ๋กœ๋Š” ShutdownMode.OnLastWindowClose๊ฐ€ ์žˆ์–ด ๋ชจ๋“  ์œˆ๋„์šฐ๊ฐ€ ๋‹ซํž ๋•Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๊ฒฉ์— ๋”ฐ๋ผ ์ด ์˜ต์…˜์„ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ด๋ฆ„ ํ˜ผ๋™ ์ฃผ์˜: ํ”„๋กœ์ ํŠธ์—์„œ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” MainWindow.xaml ํŒŒ์ผ์€ ๋‹จ์ˆœํžˆ WPF์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ์ด๋ฆ„์ผ ๋ฟ์ด๋ฉฐ, Application ํด๋ž˜์Šค์˜ MainWindow ์†์„ฑ๊ณผ๋Š” ์ง์ ‘์ ์ธ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์ด๋ฅผ ํ˜ผ๋™ํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•˜๋ฉฐ, ํ•„์š”์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์ด๋Ÿฐ ์˜คํ•ด๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ์˜๋„์ ์œผ๋กœ ์œˆ๋„์šฐ ์ด๋ฆ„์„ MainWindow๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ์ •ํ•˜๋Š” ํŽธ์ž…๋‹ˆ๋‹ค.

3. Window


Window๋Š” Application์„ ํ†ตํ•ด ์ฒ˜์Œ ์‹œ์ž‘๋˜๋Š” ์œˆ๋„์šฐ๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ํŒ์—…์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์ปจํŠธ๋กค์ž…๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋Š” ContentControl๋ฅผ ์ƒ์† ๋ฐ›์œผ๋ฉฐ, FrameworkElement๋กœ๋ถ€ํ„ฐ ํŒŒ์ƒ๋œ ๋ชจ๋“  ์ปจํŠธ๋กค ์ค‘์—์„œ ์œ ์ผํ•˜๊ฒŒ Parent ์†์„ฑ์„ ์ง€์ •ํ•  ์ˆ˜ ์—†๋Š” ํŠน๋ณ„ํ•œ ์ปจํŠธ๋กค์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ์ „ํ†ต์ ์ธ ๋””์ž์ธ์˜ ์œˆ๋„์šฐ ์Šคํƒ€์ผ์„ ์ œ๊ณต ๋ฐ›์ง€๋งŒ ContentControl์˜ ํŠน์„ฑ์„ ์ด์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋””์ž์ธ์˜ ์œˆ๋„์šฐ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค.

4. StackPanel


StackPanel์€ ์ฃผ๋กœ ํ•œ ๋ฐฉํ–ฅ์œผ๋กœ ์ž์‹ ์š”์†Œ๋“ค์„ ์ •๋ ฌํ•  ํ•„์š”๊ฐ€ ์žˆ์„ ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ๋ ˆ์ด์•„์›ƒ ์ปจํŠธ๋กค์ž…๋‹ˆ๋‹ค. ์ด ์ปจํŠธ๋กค์€ ํŠนํžˆ ๊ฐ„๋‹จํ•œ ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•˜๋ฉฐ, ListBox๋‚˜ DataGrid์™€ ๊ฐ™์€ ItemsPresenter๋ฅผ ํ™œ์šฉํ•˜๋Š” ItemsControl ๊ธฐ๋ฐ˜์˜ ์ปจํŠธ๋กค ๋‚ด์—์„œ ์ž์‹ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ปจํ…Œ์ด๋„ˆ๋กœ๋„ ์ž์ฃผ ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค.

StackPanel์˜ Orientation ์†์„ฑ์€ ์ž์‹ ์š”์†Œ๋“ค์ด ์„ธ๋กœ(Vertical) ๋˜๋Š” ๊ฐ€๋กœ(Horizontal) ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐฐ์—ด๋˜๋Š”์ง€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  StackPanel ์™ธ์— ๋‹ค๋ฅธ ์ปจํŠธ๋กค๋“ค๋„ Orientation ์†์„ฑ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด, ์ž์‹ ์š”์†Œ๋“ค์˜ ๋ฐฐ์—ด ๋ฐฉํ–ฅ์„ ์œ ์—ฐํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์— ํ•ด๋‹นํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ํŠธ๋กค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • WrapPanel
  • UniformGrid

์ด๋“ค ๊ฐ๊ฐ์€ ํŠน์ • ์‚ฌ์šฉ ์ƒํ™ฉ์— ๋”ฐ๋ผ UI ๊ตฌ์„ฑ์— ๋งค์šฐ ๊ฐ•๋ ฅํ•œ ํŽธ์˜์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Grid์™€ ๊ฐ™์€ ๋” ๋ณต์žกํ•˜๊ณ  ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ๋ ˆ์ด์•„์›ƒ ์ปจํŠธ๋กค์˜ ์กด์žฌ๋กœ ์ธํ•ด, ๊ฐœ์ธ์ ์œผ๋กœ๋Š” StackPanel์„ ๊ทธ๋ ‡๊ฒŒ ์ž์ฃผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (๊ฐœ์ธ ์ทจํ–ฅ)

Orientation์„ ์‚ฌ์šฉํ•˜๋Š” WrapPanel๊ณผ UniformGrid์ปจํŠธ๋กค๋„ ์•„์ฃผ ํŠน์ดํ•˜๊ณ  ์žฌ๋ฐŒ์œผ๋‹ˆ StackPanel๊ณผ ํ•จ๊ป˜ ์‚ดํŽด๋ณด๋ฉด ์•„์ฃผ ์ข‹์Šต๋‹ˆ๋‹ค.

5. Grid


WPF ๋ ˆ์ด์•„์›ƒ ์š”์†Œ์—์„œ Grid์˜ ์กด์žฌ๋Š” ๊ฐ€์žฅ ๋†’์€ ๋น„์ค‘๊ณผ ์ค‘์š”์„ฑ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ํŠนํžˆ ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์„ ์ •๋„์˜ ์œ ์—ฐํ•จ๊ณผ ํ™•์žฅ์„ฑ์„ ๊ฐ€์ง€๋ฉฐ Canvas์™€ ๋”๋ถˆ์–ด ์œ ์ผํ•˜๊ฒŒ ์ค‘์ฒฉ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค๊ณ„๋˜์–ด ์žˆ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ~StackPanel ๊ฐ™์€ ๊ฑด ๋นผ๊ณ ~

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

Grid๋Š” ํ–‰๊ณผ ์—ด์„ (๊ฐ๊ฐ RowDefinition, ColumnDefinition)์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ํŠน์ง•์ž…๋‹ˆ๋‹ค. ๋” ๋‚˜์•„๊ฐ€ Width ๋˜๋Š” Height์˜ Stretch๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜์‘ํ˜• ๋ ˆ์ด์•„์›ƒ ์„ค๊ณ„๋ฅผ ํ•  ๋•Œ์—๋„ ๋งค์šฐ ํšจ๊ณผ์ ์ด๊ณ  ์ง๊ด€์ ์ž…๋‹ˆ๋‹ค. ๋‹จ CSS์™€ ๊ฐ™์ด ์กฐ๊ฑด๋ถ€๋กœ ๋ฐ˜์‘ํ˜• ํฌ๊ธฐ ์ œ์–ด๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ค€ ๊นŒ์ง€๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ถ€๋ถ„์€ ์ง์ ‘ Grid๋ฅผ ์ƒ์† ๋ฐ›์•„ ๊ตฌํ˜„ํ•˜๋ฉด ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค. (๋ง‰ ์•„์ด๋””์–ด๊ฐ€ ๋– ์˜ค๋ฅด๋„ค์š”.)

๊ทธ๋ฆฌ๊ณ  Grid๋Š” Attached ํƒ€์ž…์˜ Row/Column, RowSpan/ColumnSpan ๊ณผ ๊ฐ™์€ ์†์„ฑ์„ ์ œ๊ณตํ•˜์—ฌ ์ž์‹ ์ปจํŠธ๋กค์—์„œ ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž์‹์˜ ํ–‰/์—ด ์œ„์น˜๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ํŠน์ง•์ž…๋‹ˆ๋‹ค.

Grid.Row
Grid.Column
Grid.RowSpan
Grid.ColumnSpan

WPF ์ž…๋ฌธ์ž๋ผ๋ฉด Grid๋Š” ์งˆ๋ฆฌ๋„๋ก ํ•ด๋„ ์ข‹์œผ๋‹ˆ ๋ ˆ์ด์•„์›ƒ์„ ๋‹ค์–‘ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด๋ณด๊ธฐ๋ฅผ ๊ถŒํ•ฉ๋‹ˆ๋‹ค.

6. Border


Border ์ปจํŠธ๋กค์€ WPF์—์„œ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ ๋””์ž์ธ ์š”์†Œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ด ์ปจํŠธ๋กค์€ ๋‹จ์ˆœํ•œ ๊ฒฝ๊ณ„๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๋ผ์ธ์„ ๋””์ž์ธ์  ์š”์†Œ๋กœ ํ™œ์šฉํ•  ๋•Œ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ž์‹ ์š”์†Œ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์–ด, ๋ฉ”์ธ ๋ ˆ์ด์•„์›ƒ์˜ ๊ฒฝ๊ณ„์„ , ItemsControl ๊ธฐ๋ฐ˜ ์ปฌ๋ ‰์…˜์˜ ๊ตฌ๋ถ„, GroupBox ์˜์—ญ, Button์˜ ๊ฒฝ๊ณ„, TextBox์˜ ํฌ์ปค์Šค ์˜์—ญ ๋“ฑ ๋‹ค์–‘ํ•œ ์š”์†Œ์— ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ฐธ์„๋Ÿฌ

Border๋Š” Grid์™€ ๊ฐ™์€ Panel์—์„œ ํŒŒ์ƒ๋˜์ง€ ์•Š๋Š” ๋…๋ฆฝ์ ์ธ Decorator ์ปจํŠธ๋กค๋กœ, ์ž์‹์„ ์ค‘์ฒฉํ•ด์„œ ๋‹ค๋ฃฐ ์ˆ˜๋Š” ์—†์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ Grid์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์–ด ๋” ํ’๋ถ€ํ•œ ๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์ด ์ปจํŠธ๋กค์€ Background์™€ ๊ฐ™์€ ๊ธฐ๋ณธ์ ์ธ ๋””์ž์ธ ์š”์†Œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋‹ค๋ฅธ ๋ ˆ์ด์•„์›ƒ ํด๋ž˜์Šค์—์„œ๋Š” ์ฐพ์•„๋ณผ ์ˆ˜ ์—†๋Š” ํŠน๋ณ„ํ•œ ์†์„ฑ๋“ค์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • BorderThickness
  • BorderBrush
  • CornerRadius
  • Background

Border ์ปจํŠธ๋กค์˜ ๋งค๋ ฅ์€ ๊ทธ ์œ ์—ฐ์„ฑ์— ์žˆ์Šต๋‹ˆ๋‹ค. BorderThickness ์†์„ฑ์„ ์กฐ์ ˆํ•˜์—ฌ ํ…Œ๋‘๋ฆฌ์˜ ๋‘๊ป˜๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ๋””์ž์ธ์— ๋”ฐ๋ผ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์กฐ์ •๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‘๊ป˜๋ฅผ ์กฐ์ ˆํ•˜์—ฌ ๋”์šฑ ๋šœ๋ ทํ•˜๊ฒŒ ํ…Œ๋‘๋ฆฌ๋ฅผ ๊ฐ•์กฐํ•˜๊ฑฐ๋‚˜, ๋ฏธ๋ฌ˜ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜์—ฌ ์„ธ๋ จ๋œ ๋Š๋‚Œ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  BorderBrush ์†์„ฑ์„ ์ด์šฉํ•ด ์ƒ‰์ƒ์„ ์„ ํƒํ•˜๊ฑฐ๋‚˜, ๊ทธ๋ผ๋ฐ์ด์…˜์„ ์ ์šฉํ•˜์—ฌ ์žฌ๋ฏธ์žˆ๋Š” ์Šคํƒ€์ผ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Border์˜ ํŠน์„ฑ๊ณผ ์ค‘์ฒฉ์„ ์ž˜ ํ‘œํ˜„ํ•œ ์ƒ˜ํ”Œ์ด ๋งˆ์นจ ์žˆ์–ด์š”.

๋‹จ ์ƒ‰์ƒ์€ ํ•œ ๊ฐ€์ง€ ์ƒ‰์œผ๋กœ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š”,

Html์—์„œ๋Š” border-top, border-left ์ด๋Ÿฐ ์‹์œผ๋กœ ๊ฐ๊ฐ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์ฃ , ์ฆ‰ WPF์—์„œ๋„ ์ด์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Border๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์ค‘์ฒฉํ•˜์—ฌ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

CornerRadius ์†์„ฑ์€ Border์˜ ๋ชจ์„œ๋ฆฌ๋ฅผ ๋‘ฅ๊ธ€๊ฒŒ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ถ€๋“œ๋Ÿฌ์šด ๋Š๋‚Œ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋””์ž์ธ์— ๋”ฐ๋ผ ํด๋ž˜์‹ํ•˜๊ฑฐ๋‚˜ ํ˜„๋Œ€์ ์ธ ๋Š๋‚Œ์„ ์ค„ ์ˆ˜ ์žˆ์–ด, ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๋ฐ ์•„์ฃผ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ, WPF์—์„œ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ปจํŠธ๋กค๋“ค์ด ๊ฒฝ๊ณ„์„ ์„ ์ง์ ‘์ ์œผ๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— Border๋ฅผ ๋‹ค์–‘ํ•˜๊ฒŒ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด CustomControl๊ณผ ๊ฐ™์€ ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์˜ ์ปจํŠธ๋กค์„ ๊ตฌํ˜„ํ•  ๋•Œ๋„ ๋” ํ’๋ถ€ํ•˜๊ณ  ๋‹ค์–‘ํ•œ ์š”๊ตฌ์‚ฌํ•ญ์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ตฌํ˜„ํ•ด ๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

7. DataContext


WPF์˜ DataContext๋Š” ๋งค๋ ฅ์ ์ธ ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์œ ํ˜•์„ ์ง€์›ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์œ ์—ฐ์„ฑ, ํ™•์žฅ์„ฑ๊ณผ ๊ฐ™์€ ์„ค๊ณ„ ์ ์ธ ๋ฉด์— ์žˆ์–ด ํ•ต์‹ฌ์ ์ธ ์š”์†Œ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. DataContext๋ฅผ ์ด์šฉํ•˜๋ฉด ๋‹จ์ˆœํ•œ ๊ฐ์ฒด๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ๋ฌธ์ž์—ด, ์ •์ˆ˜, ์ธ์Šคํ„ด์Šค ๊ฐ์ฒด, ViewModel, ์‹ฌ์ง€์–ด๋Š” ์ปจํŠธ๋กค๊นŒ์ง€ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์œ ํ˜•์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” MVVM ํŒจํ„ด์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์™€ UI๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ถ„์‚ฐํ™” ๊ฐœ๋ฐœ์„ ์šฉ์ดํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, DataContext๋Š” ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„๋ฅผ ํ†ตํ•ด ๊ณ„์ธต์ ์ธ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถ€๋ชจ ์š”์†Œ์˜ DataContext๊ฐ€ ์ž์‹ ์š”์†Œ์—๊ฒŒ ์ƒ์†๋˜๋Š” ํŠน์„ฑ์€ ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์˜ ํ๋ฆ„์„ ์‰ฝ๊ฒŒ ํŒŒ์•…ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

DataContext๋Š” ์ž์‹ ์—๊ฒŒ ์ง์ ‘ ํ• ๋‹น๋œ ๋ฐ์ดํ„ฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋” ์ƒ์œ„์˜ ๋ถ€๋ชจ ์š”์†Œ์˜ DataContext๋ฅผ ์ฐพ์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ•˜์œ„ ์š”์†Œ๋“ค์€ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ€๋ชจ ์š”์†Œ์—์„œ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ฐ์ดํ„ฐ์˜ ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ์ผ๊ด€์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

DataContext์˜ ๋ฐ์ดํ„ฐ ์ „ํŒŒ๋Š” ์ผ์ข…์˜ ์ƒ์† ์ฒด์ธ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฐ ์š”์†Œ๋Š” ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ€๋ชจ ์š”์†Œ์—์„œ ์ฐพ์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ฐ์ดํ„ฐ์˜ ์œ ์—ฐํ•œ ํ™œ์šฉ๊ณผ ์ฝ”๋“œ์˜ ๊ฐ„๊ฒฐ์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ์žˆ์–ด ํ•ต์‹ฌ์ ์ธ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

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

์˜์กด์„ฑ ์ฃผ์ž…, ์ด๋ฒคํŠธ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

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

๊ฒฐ๋ก ์ ์œผ๋กœ, ์šฐ๋ฆฌ๋Š” DataContext๋ฅผ ์ดํ•ดํ•˜๊ณ  ์ด๋ฅผ ๊นŠ์ด ์žˆ๊ฒŒ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. DataContext์˜ ๊ฐœ๋…์„ ์ง€์†์ ์œผ๋กœ ์—ฐ๊ตฌํ•˜๊ณ  ํ™œ์šฉํ•˜์—ฌ MVVM ํŒจํ„ด๊ณผ ๋ชจ๋“ˆํ™”๋ฅผ ํ†ตํ•œ ํ”„๋ ˆ์ž„์›Œํฌ ์„ค๊ณ„๋ฅผ ๋”์šฑ ํšจ๊ณผ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

8. Button


Button์˜ ์„ค๊ณ„ ๊ตฌ์กฐ๋Š” WPF์˜ ๋ฐฉํ–ฅ์„ฑ๊ณผ ๊ทธ ์ฒ ํ•™์„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. Button์€ ContentControl ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›์•„ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์ด๋ฅผ ํ†ตํ•ด ๋ฌธ์ž์—ด, ์ด๋ฏธ์ง€, ๋˜๋Š” ๋” ๋ณต์žกํ•œ ๋ ˆ์ด์•„์›ƒ์„ Button์˜ ๋‚ด์šฉ์œผ๋กœ ์‰ฝ๊ฒŒ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋” ๋‚˜์•„๊ฐ€, Template ์†์„ฑ์„ ํ†ตํ•ด Button์˜ ์™ธํ˜•์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ œ์–ดํ•˜๊ณ  ์žฌ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ์„ค๊ณ„์  ์›๋ฆฌ๋Š” Button์—๋งŒ ๊ตญํ•œ๋˜์ง€ ์•Š๊ณ  WPF์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฑฐ์˜ ๋ชจ๋“  ์ปจํŠธ๋กค์— ์ ์šฉ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, Button์˜ ๊ตฌ์กฐ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ์‚ฌ์šฉ์žํ™”(customizing)ํ•˜๋Š” ์—ฐ์Šต์€ WPF๋ฅผ ์ดํ•ดํ•˜๊ณ  ๋ฐฐ์šฐ๋Š” ๋ฐ ์•„์ฃผ ์ข‹์€ ์ถœ๋ฐœ์ ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Button์€ 'Clickโ€™์ด๋ผ๋Š” ์ค‘์š”ํ•œ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ด๋ฒคํŠธ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ Button์—์„œ MouseDown๊ณผ MouseUp ์ด๋ฒคํŠธ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐœ์ƒํ•œ ํ›„์— ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. Button์€ ์ด ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ๋“ค์„ ๋‚ด๋ถ€์ ์œผ๋กœ (Click์„ ์œ„ํ•ด) ์†Œ๋น„ํ•˜๋ฏ€๋กœ, ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ์˜ ์ถ”๊ฐ€์ ์ธ ์ด๋ฒคํŠธ ์ „ํŒŒ๋Š” ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฒ„๋ธ”๋ง/ํ„ฐ๋„๋ง์„ ํ•ธ๋“ค๋งํ•  ๋•Œ Button ์š”์†Œ๊ฐ€ ์ค‘๊ฐ„์— ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ด๋ฅผ ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ธฐ๋ณธ์ ์œผ๋กœ Click ์‹œ ICommand๋ฅผ ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ๋„๋ก Command ์†์„ฑ๋„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— MVVM ํŒจํ„ด์—์„œ๋„ ์ด๋ฒคํŠธ ๋กœ์ง์„ ViewModel๋กœ ์†์‰ฝ๊ฒŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ, Button ์ปจํŠธ๋กค์„ ํ†ตํ•ด ContentControl ๊ตฌ์กฐ์— ๋Œ€ํ•ด ๊นŠ์ด ์žˆ๊ฒŒ ์—ฐ๊ตฌํ•˜๊ณ  ๋‹ค์–‘ํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด๋ณธ๋‹ค๋ฉด WPF ๊ธฐ์ˆ ๋ ฅ์„ ๋†’์ด๋Š” ๋ฐ ์žˆ์–ด ์•„์ฃผ ์ค‘์š”ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

9. Property


WPF์—์„œ์˜ ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ ์‚ฌ์šฉ

WPF์—์„œ ์ปจํŠธ๋กค์€ ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ํ™•์žฅ์„ฑ๊ณผ ์œ ์—ฐ์„ฑ์„ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. XAML์—์„œ ์ปจํŠธ๋กค์˜ Background, Margin, Content ๋“ฑ์˜ ์‹œ๊ฐ์ ์ธ ์†์„ฑ์€ ์ผ๋ฐ˜์ ์ธ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹Œ ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ๋กœ ์„ค์ •๋˜๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด XAML ์ƒ์—์„œ ์†์„ฑ ๊ฐ’์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ ๋‚ด๋ถ€์ ์œผ๋กœ ์ฝœ๋ฐฑ ์ด๋ฒคํŠธ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ๊ณผ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐ™์€ WPF์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋ฏ€๋กœ, ๋ณต์žกํ•˜๊ณ  ํ’๋ถ€ํ•œ UI ๊ตฌํ˜„์„ ์œ„ํ•ด ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.

๋ทฐ๋ชจ๋ธ๊ณผ์˜ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ (์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ)

๋ทฐ๋ชจ๋ธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ์™€ (UI ์ปจํŠธ๋กค) ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ ๊ฐ„์˜ ์—ฐ๊ฒฐ์€ WPF์˜ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ๋ทฐ๋ชจ๋ธ ๋‚ด ํ”„๋กœํผํ‹ฐ๋Š” INotifyPropertyChanged ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ๊ฐ’ ๋ณ€๊ฒฝ์„ ์•Œ๋ฆด ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด UI์— ๋ฐ”์ธ๋”ฉ์ด ๋œ ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ ์†์„ฑ ๊ฐ’์ด ๋™์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ทฐ๋ชจ๋ธ์—์„œ๋Š” ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹Œ ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ”ํžˆ ์‹ค์ˆ˜ ํ•˜๋Š” ํ˜ผ๋™ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

์ฃผ์š” ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ์˜ ์‚ฌ์šฉ ๋ฐ ๊ณ„์ธต์  ์„ค๊ณ„ ์ดํ•ด

DataContext, Background, Content, Margin๊ณผ ๊ฐ™์€ ์ฃผ์š” ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ๋“ค์€ FrameworkElement์™€ Control ํด๋ž˜์Šค์—์„œ ํŒŒ์ƒ๋˜๋ฉฐ, ์ด๋Ÿฌํ•œ ํ”„๋กœํผํ‹ฐ๋“ค์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐ์ดํ„ฐ ํ‘œํ˜„๊ณผ ๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ์— ํ•ต์‹ฌ์ ์ธ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋‹ค์–‘ํ•˜๊ฒŒ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•˜๋Š” ๊ฒƒ๋„ ์œ ์šฉํ•˜์ง€๋งŒ, ๊ณ„์ธต์  ๊ตฌ์กฐ๋ฅผ ์ž˜ ์ดํ•ดํ•˜๊ณ  ๊ธฐ์กด์˜ ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ๋ฒ•์€ WPF์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ๋” ์ž˜ ์ดํ•ดํ•˜๊ณ  ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์˜์กด์„ฑ ํ”„๋กœํผํ‹ฐ๋“ค์€ WPF์˜ ํŠน์ง•์ ์ธ ๋ถ€๋ถ„์œผ๋กœ, ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ณด๋‹ค ์„ธ๋ฐ€ํ•˜๊ณ  ํšจ์œจ์ ์ธ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋•์Šต๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ๋“ค์˜ ๊ณ„์ธต์  ๊ตฌ์กฐ์™€ ํŠน์„ฑ์„ ์ดํ•ดํ•˜๊ณ  ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์€ WPF ๊ฐœ๋ฐœ์—์„œ ์ค‘์š”ํ•œ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ดํ•ด๋Š” ํšจ๊ณผ์ ์ธ ์ปค์Šคํ…€ ์ปจํŠธ๋กค ๊ฐœ๋ฐœ์—๋„ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

10. Style


FrameworkElement๋Š” ์ปจํŠธ๋กค์˜ ๋ชจ๋“  ์†์„ฑ์„ ์ •์˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” Style์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ FrameworkElement์—์„œ ํŒŒ์ƒ๋œ ๋ชจ๋“  ํด๋ž˜์Šค๋Š” ์ด ์Šคํƒ€์ผ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํƒ€์ผ์€ ์ปจํŠธ๋กค์— ์ง์ ‘ StaticResource ๋˜๋Š” DynamicResource๋ฅผ ์ ์šฉํ•˜๊ฑฐ๋‚˜, App.xaml์ด๋‚˜ Application.Resources ์ปฌ๋ ‰์…˜์— x:Key๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์Šคํƒ€์ผ์„ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ ์ผ๋ฐ˜์ ์œผ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ๊ธฐ๋ณธ App.xaml:

<Application>
    <Application.Resources>
    </Application.Resources>
</Application>

// ๋งค๋‰ด์–ผ App:

internal class App : Application
{
    public App()
    {
        // Resources.Add(์Šคํƒ€์ผ ๋ฆฌ์†Œ์Šค);
        // ๋˜๋Š”
        // Resources.MergedResourceDictionaries.Add(๋ฆฌ์†Œ์Šค ๋”•์…”๋„ˆ๋ฆฌ);
    }
}

๋˜ํ•œ,CustomControl์˜ Generic.xaml์„ ํ†ตํ•ด ๊ธฐ๋ณธ ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค (์ด์— ๋Œ€ํ•œ ์„ค๋ช…์€ ํ›„๋ฐ˜๋ถ€์— ์žˆ์Šต๋‹ˆ๋‹ค).

DynamicResource ์‘์šฉ

ํ…Œ๋งˆ๋‚˜ ๋‹ค๊ตญ์–ด ๊ตฌํ˜„์„ ์œ„ํ•ด DynamicResource๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ResourceDictionary๋ฅผ ์ˆ˜๋™์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ  ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ์œ ์—ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” App.xaml์„ ์‚ฌ์šฉํ•˜๊ธฐ๋ณด๋‹ค๋Š” ๋งค๋‰ด์–ผ App ํด๋ž˜์Šค ๊ตฌ์กฐ๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ResourceDictionary์˜ ๋“ฑ๋ก๊ณผ ์ œ๊ฑฐ๋ฅผ ์ง์ ‘ ์œ ์—ฐํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•ฉ๋‹ˆ๋‹ค.

์ƒ๊ฐํ•ด๋ณด๋‹ˆ ResourceDictionary๋ฅผ ์Šค์œ„์นญ ํ•˜๋Š” ํŠธ๋ฆฌ๊ฑฐ ํ˜•ํƒœ์˜ ์Šคํƒ€์ผ์„ ๋งŒ๋“ค์–ด๋ณด๋Š” ๊ฒƒ๋„ ์•„์ฃผ ์œ ์šฉํ•  ๊ฒƒ ๊ฐ™๋„ค์š”?

๋‹ค๋งŒ ์ €๋Š” ๊ฐœ์ธ์ ์œผ๋กœ CustomControl์„ ํ†ตํ•œ ๋ชจ๋“ˆํ™”, ๋ถ„์‚ฐํ™”๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ณต์šฉ๋ฆฌ์†Œ์Šค๋ฅผ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” CustomControl์˜ ๊ฐœ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๋Š” ๋ฐฉ์‹์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ จ ๋งํฌ ๋ณด๊ธฐ


5 Likes