[S2, EP.1] WPF 스터디 5회 후기 | 이재웅

안녕하세요 이재웅입니다!
2023년 3월 18일 (지난주 토요일) 있었던 WPF 스터디 5회 후기를 남겨봅니다.


인원

저를 포함해 오프라인 32명, 온라인으로 약 10명의 참여자분들과 함께 했습니다.
이번에는 처음으로 유튜브 실시간도 함께 진행했는데요. 동시 진행은 처음이라 미흡한 부분도 많이 있었지만 @이광석 광석님의 사전 온라인 준비 지원 및 현장 도움을 통해 잘 마무리할 수 있었습니다. :smile:

장소

이번에도 시즌 1과 동일한 장소인 가산역 온라인끝 세미나실에서 진행되었습니다.
시즌 2 종료 시점인 8회까지도 계속 같은 장소에서 예정되어 있습니다.

  • [온라인끝] 서울특별시 금천구 서부샛길 606 A동 16층 1608호
  • 매주 토요일 13:00 ~ 17:00

후원

이번 회차에도 앞서 예고드린대로 디모이님의 간식/음료 후원이 있었습니다.
다시 한번 정말 감사드립니다.

image

간식/음료 인증샷~! 참고로 남은 음식은 제겁니다.

열기

지난번 4회차(시즌1)를 마무리 할 때 마다 한 주 쉬기로 규칙을 만들었었죠. 그래서 걱정과 두려움이 많았습니다. (잊혀질까봐…)

다행이도 많은 분들께서 시즌 2를 신청해주셨고 이번에는 온라인 실시간까지 개설하게 되었습니다.

그리고 오프라인을 원하시는분들이 많으셔서 자리가 부족할까 시작 전 까지 내심 걱정을 했는데 다행히 딱 정원이 와주셨습니다.

그래서 다음부터는 단톡방 투표를 통해 정확한 수요를 체크하기로 했습니다. (여러분들의 아이디어!)

그리고 제가 사진을 깜빡하고 못 찍었습니다. ㅠㅠ

너무 아쉬워요… 다음번에는 여러분들도 추억을 간직할 사진을 몇 장 찍어주시면 좋을 것 같습니다!!

온라인

중간에 마이크가 꺼지는 바람에 실시간 참여자분들이 전화도 오고 난리가 났었습니다. :smile:
저는 또 라이브중이라고 전화를 무시하려했죠… 웃긴 해프닝이었습니다.

유튜브 라이브채팅도 익숙해지면 재밌어질 것 같습니다. :rofl:

image

유튜버로 새롭게 태어난… @jamesnet214

피드백

역시나 피드백 단골 손님 빠르다는 의견이 많았고요. (점점 빠르게… 알라르간도)
그 외에도 시즌 2 참여자분들의 CustomControl 이해도에 대한 문제 등이 있었습니다.

그래서 정리해보면,

  • 속도가 빠름
  • 어려움
  • 단축키 설명 (혼자 막 휙휙 함)
  • CustomControl 이해도 문제
  • 신규 참여자 한정 시즌 1 복습의 부재
  • Jamesnet.WPF NugetPackage의 Documentation의 부재

대부분 당장 해결할 수 있는 문제는 아니지만 이번주에는 더욱 더 피드에 대한 내용을 신경 써서 대폭 반영해 보도록 하겠습니다.

대신 이번 내용이 숨 쉬듯 몸에 벨때까지 열번 백번 반복해주셔야겠죠!
이게 가장 빠른 피드백 해결 방법입니다. :smile:

영상 공개

시즌 1 (1회부터 4회까지)은 아쉽게도 영상을 남기지 못했지만 시즌 2부터는 영상도 공개 예정입니다.

(편집의 압박으로 4시간 전체 영상으로 나갑니다…)

다만 이 콘텐츠는 저 혼자 만드는게 아닌 온/오프라인을 통해 실시간으로 참여해주시는 분들의 노고와 함께 만들어지기 떄문에 전체 공개는 시즌이 종료되는 시점을 기준으로 공개될 예정입니다.

공개는 어떤 방식이 좋을까요?

  • 더 글로리처럼 전체공개
  • 카지노처럼 속터지게 한편 씩 공개

댓글 반응을 통해 결정하겠습니다. :rofl:

오프닝

시즌1에서 했던 것 처럼 제 소개를 다시한번 했습니다. 기존 참여자분들도 계시기에 매우 쑥쓰럽더라고요. 그대로 재탕 했습니다.

아 그리고 시즌1 관련 GitHub Repository, 히스토리들을 한번 살펴보고 내용에 대한 언급도 아주 짧게 잠깐 했었죠.

내용

시즌1이 끝나면서 예고드린 것 처럼 카카오톡 만들기를 주제로 시즌2 시작을 열었습니다.

이번에는 별도의 레포지터리를 준비해 두었습니다.

jamesnet214/kakaotalk (github.com)

내용들을 본격적으로 한번 떠올려 볼까요?

1. Kakao 프로젝트 생성

  • Starter
  • App : JamesApplication
  • CreateShell

먼저 WPF Application 프로젝트 템플릿을 통해 Kakao 프로젝트를 만들었어요.
(Visual Studio 2022 .NET 7.0)

App는 Jamesnet.WPF 누겟 패키지의 JamesApplication 클래스를 상속받았죠. 그리고 잠깐이지만 Application을 어떻게 구조화 했는지에 대해서도 휙 살펴봤습니다. 시즌1에서는 실제로 다 구현해본 내용들이었기 때문에 영상으로 남기지 않은 것이 많이 아쉬웠습니다.

2. Kakao.Forms 프로젝트 생성

  • KakaoWindow : JamesWindow

CustomControl (사용자 지정 라이브러리)를 통해 메인 윈도우가 위치할 프로젝트를 만들었어요.

그리고 KakaoWindow를 만들고 애플리케이션 쪽 CreateShelll에서 선언했죠.

3. Kakao.Login 프로젝트 생성

  • LoginContent : JamesContent

이때부터 Export Template (탬플릿 내보내기) 기능을 적극 활용해서 귀찮은 구조 작업들을 최소화 했어요~

4. Region

  • MainRegion (KakaoWindow)

시즌1 기억나시나요? Region을 자동으로 추가하지 않고 Region 커스텀컨트롤을 만들어 DP를 통해 직접 Region을 IRegionManager를 통해 추가해주었었죠. 이렇게 함으로 인해 Region에 관련한 작업들을 좀 더 정교하게 할 수 있겠습니다.

5. ViewModules

  • IModule

여기에서 모듈을 신나게 추가했죠. 복붙 복붙…

6. DirectModules

  • #Region.RegisterViewWithRegion (Resolve)

곧 폐기될 운명이었지만 RegisterViewWithRegion를 사용하기 위한 구간으로 잠깐 등장했었죠. 그리고 나중 후반부에서 이 기능이 Instance를 등록하는 척만 하는 사례를 함께 확인하고 새로운 해결방법인 Kakao.Main 프로젝트를 생성했었습니다. 기억 나시죠? 제 텐션이 가장 높을때가 아니었나 싶어요. :rofl:

7. ViewModel

  • ObservableBase (Jamesnet.WPF.Mvvm)

CommunityToolkit.Mvvm ObservableObject를 상속받은 클래스를 사용했죠.

8. Login Command

  • [RelayCommand] attribute

코드 자동생성 기능을 위한 어트리뷰트 사용~

9. Kakao.Main 프로젝트 생성

  • MainContent : JamesContent

앞서 언급한 RegisterViewWithRegion의 문제점을 해소하기 위해 MainRegion이 로드되는 시점을 확보하기 위해 이 프로젝트를 만들었어요.

그리고 이 때 프로젝트간의 계층적인 구조에 대해서도 한번 더 강조했습니다. 기억나시죠? 왜 Partial 폴더 안에 UI 계층 구조를 따지지 않고 다 함께 밀어 넣었는지 라든지…!

그리고 ContentRegion을 추가해서 텝 기능 역활에 필요한 영역을 준비했어요. (아래에서 ChatsContent, FriendsContent, MoreContent가 Activate 되었죠!)

10. Active MainContent

  • IRegionManager
  • IContainerProvider

해당 Region을 찾기 위해 ViewModel 생성자로부터 IRegionManager를 주입 받았고 참조 되어있지 않은 뷰를 이름만으로 찾기 위해 이번에는 IContainerProvider를 주입 받아 객체를 찾는 과정이었어요.

하도 많이 해서 기억 나실거에요~ Contains → Activate 반복~

11. Logout Command

  • Active LoginContent

반복이죠… LoginContent 찾아서 Activate 반복~

12. Contents 생성

  • Kakao.Chats
  • Kakao.Friends
  • Kakao.More

각각의 텝 안에 들어갈 프로젝트를 만들었습니다. 역시 탬플릿 내보내기를 통해 반복~~

13. VerticalMenuList 추가

  • ListBox/ListBoxItem

좌측 메뉴를 표현하기 위한 CustomControl을 만들었죠. 단골 손님인 GetContainerForItemOverride와 함께…


그밖에도 Kakao.Core 프로젝트를 만들어서 RegionNameManager, ContentNameManager를 통한 Region, View 인스턴스 관리 방법도 기억이 납니다.

그리고 Solution 폴더 네이밍에 관한 썰도 잠깐 풀었고요.

Based, Foundation, Partial, Studio…

Template 내보내기를 아주 적극적으로 사용했죠. 단 CustomControl 구조에 익숙하지 않다면 좀 더 손을 쓰는 것이 좋습니다!!


끝으로

제가 준비한 WPF 스터디 5회 내용은 여기까지입니다.

이번 WPF 스터디를 참여해주신 온/오프라인 모든 분들에게 다시한번 감사인사 드립니다.

그리고 이 스터디를 통해 더 나아가 WPF와 Xamarin, Xaml, Uno, Avalonia UI등의 크로스플랫폼 경쟁력을 더욱 더 끌어올릴 수 있는 좋은 계기가 되었으면 좋겠습니다!!

감사합니다. 이재웅 드림

ps. @dimohy 디모이님 다시한번 이번 간식/음료 후원 감사드립니다. :smile:

회사/단체/개인의 간식/음료 후원 제안은 언제든지 열려있습니다!

@이광석 Youtube 스트리밍, OBS 설정, 리허설 지원 감사드립니다!

그리고 이번 6회 정말 기가막히게 재밌을거에유!!

13개의 좋아요

조금이나마 도움을 드릴 수 있어서 다행입니다 :slight_smile:
개인 사정 상 시즌2는 참여하지 못할까 아쉬울뻔 했으나 다행히 이번 시즌부턴 온라인 스터디도 오픈되어 지식을 채울 수 있게 매우매우매우 기뻤습니다.

ps. 영상 중간에 필요한 단축키 기억안나셨다는거 남겨드려요!
해당 페이지의 사용하지 않는 using 정리 단축키 → ctrl + r + g

4개의 좋아요

진행이 좀 빠르긴 했지만 영상이 있어서 집와서 다시 보면서 정리했네요~
역시 영상이 있는게 좋은 것 같습니다 ㅋㅋㅋ
2회차부터는 더 재밌는 내용이 나올 것 같아서 기대하고 있습니다~ 토요일에 뵐께요^^
그리고 VisualStudio 확장 중에 Code Clean On Save 라는 것도 있습니다. 변경하고 저장할때 안 쓰는 using 들 지워주고 정렬 맞춰줍니다 ㅎㅎ

4개의 좋아요

지방에 있어서 시즌1에 참여하지 못하여 아쉬움이 있었는데,
시즌2에서는 온라인으로 병행 해주셔서 너무 고마웠습니다.
그런데, 시즌2 1회차 듣다보니 시즌1 참여하지 못한 아쉬움이 더 크게 느껴집니다.

개인적으로는 시즌2 1회 강의 들으면서 알게 된 점, 좋았던 점은

  1. 예전에 올려 주셨던 lol 프로젝트 소스 보면서 초보자에겐 구조를 이해하기엔
    힘들었는데, 1회차 강의 후에는 프로그램 구조를 이해할 수 있게 되었습니다.
    아무래도 초보자에겐 app 객체로 시작하는 것만 보았고, Custom Control 사용하는데
    익숙하지 않아서 그랬던 것 같습니다.

  2. WPF는 저에겐 오래된 숙제였는데요, 찰스페졸드 책은 아주 오래전에 구매한 후에
    책장 한 켠에서 장식용으로 전락한 상태였습니다.
    최근에 용기(?)를 내어 WPF로 작은 프로그램 개발하면서 본격적으로 시작하였었는데,
    그때 View와 ViewModel 연결하는 방법과 화면 Navigation에서 고민을 한 적이 있었습니다.
    이번 회차 강의를 들으면서 WireDataContext와 Region을 사용하는 것을 보고
    고민했던 부분이 해소되었습니다.

아직 WPF 초보라 알아야 할 것이 너무 많지만, 이번 강의와 앞으로의 강의를 통해
열심히 따라 가보도록 하겠습니다.

모니터 2개로 왼쪽, 오른쪽 화면을 빨리 전환하다 보니 너무 어지럽긴 했어요 :joy:

감사합니다.

4개의 좋아요

나중에 전체 공개 해주신다니, 정말 감사드립니다>!

4개의 좋아요

Visual Studio 2022 단축키 목록

  • 새로운 Using 추가: Ctrl + .
  • 불필요한 Using 제거: Ctrl + . (쩜)
  • 현재 라인 삭제: Ctrl + X
  • Visual Studio 탭 전환: Ctrl + Tab
  • 이전 Visual Studio 탭으로 이동: Ctrl + Shift + Tab
  • 현재 파일 저장: Ctrl + S
  • 프로젝트 빌드: Ctrl + Shift + B
  • 프로젝트 실행 (디버그 없음): Ctrl + F5
  • 디버그 모드로 실행: F5

기억나는데로 추가해보도록 할게요~

2개의 좋아요

프로젝트 템플릿이 인상적이었습니다.
이번주도 기대 합니다.

그런데 혹시 시그날R로 하시는 이유는 개발 비용 떄문이 맞을까요 ?
그리고 시그날R이 동시 접속 처리나 멀티 쓰레드에서 안전 할까요 ?

3개의 좋아요

@이광석 온라인 할 수 있을지 막막했는데 감사드려요!! ㅠㅠ

@EnjoyDev 속도가 더 빨라지면 안될탠데 걱정입니다. ㅠㅠ

@dhryu 워낙 잘하셔서~ 회를 거듭할 수록 숙련도는 금방 올라갈거라 생각해요!! 적극적인 온라인 실시간 참여 감사드립니다!! :smile:

@helpandplay 공개 시점에는 시즌 3가 시작되니 참여해보시면 좋을 것 같아요!

@windowmini 저도 그 부분에는 경험이 부족해서 정확한 답변 드리기는 어려울 것 같습니다. 다른 전문가분들의 답변을 기대해보겠습니다!! @jacking75

2개의 좋아요

이번에 이상 깊게 배우게 된 것은

  • 템플릿 내보내기
  • 솔루션 폴더 생성

두 가지 였습니다.

github 같은데서 오픈소스 클론받아서 열어보면 솔루션안에 폴더가 여러개가 있는걸로 보였는데 실제로 clone된 directory를 보면 폴더별로 나뉘어져있지 않아서 이건 어떻게하는건가 궁금했었습니다.

이번에 알게되어 좋았습니다.

CustomControl을 템플릿 프로젝트 내보내기를 통해 템플릿으로 관리하여 반복되는 노가다 작업을 최대한 줄일 수 있었던 것이 좋았습니다. 2017년도에 템플릿 내보내기를 아는 형님 통해서 알아뒀었는데 6년만에 꺼내든 지식이었어서 거의 새로 배운 것처럼 신선했습니다.

그래서 회사에서 새로 진행되는 솔루션을 이번에 스터디에서 배운 구조로 모두 변경했습니다.

  • 솔루션
    – 폴더
    —CustomControl 뷰 프로젝트
    —CustomControl 뷰모델 프로젝트
    —CustomControl 뷰모델 Xunit 테스트 프로젝트
    – 폴더
    —CustomControl 뷰 프로젝트
    —CustomControl 뷰모델 프로젝트
    —CustomControl 뷰모델 Xunit 테스트 프로젝트
    – 폴더
    —CustomControl 뷰 프로젝트
    —CustomControl 뷰모델 프로젝트
    —CustomControl 뷰모델 Xunit 테스트 프로젝트

이런식으로 폴더마다 CustomControl의 뷰와 뷰모델 프로젝트까지 완전히 나누고, 뷰모델도 혹시몰라 유닛테스트가 가능하도록 했습니다.

다만 조금 차이가 있게 변형한 것은, Prism을 사용하지 않고 다른방식으로 했습니다.
@aroooong 님의 pc kakaotalk 샘플에 mapping으로 뷰와 뷰모델은 데이터 템플릿으로 관리하는 방법입니다.

WPFKakaoTalk/Mappings.xaml at master · tyeom/WPFKakaoTalk (github.com)

이 방식을 이용하면 prism을 이용하지 않고 뷰와 뷰모델은 resourcedictionary 안에서 매핑할 수 있습니다. CommunityToolkit 만으로 가능하다는 의미입니다. (CommunityToolkit 안에 Generic Host가 이미 있으므로)

원래 저도 ViewLocator(ViewModelLocator 아님)와 네이밍 패턴으로 하는 방식을 선호했으나, 유지보수 차원에서 명시적으로 하려면 아무래도 스터디에서 배웠던 방식이던, 지금처럼 리소스로 관리하는 방식이던 명시적으로 어딘가에서 표현하는 방식이 있어야겠다고 생각을 조금 바꾸게 되었습니다.

언젠가 ViewLocator 방식도 다시 쓸 날이 오겠지만 이번에는 이렇게 진행해보려고 합니다.

또한 AvaloniaUI도 이런 CustomControl 방식을 해보고 싶어서 시도했는데 잘 되는 것 같긴합니다.

좋은 아키텍쳐 배워갑니다

감사합니다.

6개의 좋아요

@Vincent 기가막힌 후기, 사례 소개해주셔서 감사합니다!! :smile:

이제 6회차를 앞두고 있는 시점에서 저도 정말 많이 배우고 있네요! 다시한번 감사드립니다!!

2개의 좋아요
  1. WPF MVVM 패턴으로 개발은 하고 있었지만 실제로 어떻게 베이스로 동작하는지에 대해서는 공부하지 않아서 무시하고 개발하던 부분이 많았습니다. 처음 프로그램을 시작할 때 이런 식으로 보통 시작을 합니다라고 보여주신 부분을 동영상으로 다시 보았는데 그때서부터 자괴감이 좀 들기 시작하더라고요. 기초 이론에 충실하지 못하고 트랜드 혹은 라이브러리에만 너무 의존하려고 했구나

  2. 다들 올리셨다시피, 프로젝트 내보내기는 정말 엄청난 스킬???이였습니다. 잘 짜여진 구조 프로젝트 하나 있으면 그것을 템플릿으로 만든다는 생각은 전혀 해보지 않았어요. 너무 유익했습니다.

동영상 다시보기 서비스 혹은 인프런 강좌로 올리셔도 무방하실 듯 합니다.

시즌2 2회차 오프라인에서 뵙도록 하겠습니다~~!

4개의 좋아요

동시 접속 처리가 안전 할까요? 가 어떤 의미인지 모르겠는데.,
일반적으로 사용 했을때 멀티 스레드에서 스레드 안전 하진 않습니다.
Hub에 등록된 메서드는 비동기로 여러 클라이언트에서 호출 되기 때문에
여러 스레드가 동시에 호출 할 수 있습니다.

6개의 좋아요

와… … … … … :+1:

4개의 좋아요