<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>머리속 지우개 방지 블로그</title>
    <link>https://sslee92.tistory.com/</link>
    <description>기억은 짧고 기록은 긴 법.
내 머리 속의 지우개가 지우기 전에 기록해두기</description>
    <language>ko</language>
    <pubDate>Sun, 14 Jun 2026 18:47:01 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>루다대디</managingEditor>
    <image>
      <title>머리속 지우개 방지 블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/5500742/attach/9e98a8bb47fd4d6b8bba1360be2c3b96</url>
      <link>https://sslee92.tistory.com</link>
    </image>
    <item>
      <title>[Git] commit 이력을 모두 포함해서 Git server 마이그레이션 하기</title>
      <link>https://sslee92.tistory.com/43</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;최근 사내 Git 서버를 교체하게 되어 저장소 마이그레이션을 진행했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;단순히 파일만 복사해서 옮기는 것이 아니라,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;그동안 쌓아온 &lt;b data-index-in-node=&quot;33&quot; data-path-to-node=&quot;4&quot;&gt;모든 커밋 이력(Commit History)을 온전히 보존&lt;/b&gt;해야 했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;나중에 다시 마이그레이션을 할 때 참고하기 위해, 과정을 기록으로 남긴다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;이방법은 Git의 표준 기능을 이용하기 때문에&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;Github, GitLab, Bonobo 등 어떤 Git 서버간의 이동에도 동일하게 적용이 가능하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;마이그레이션 전 준비사항&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;로컬 작업 내역 push&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;기존 서버에 Push하지 않은 로컬 작업 내용이 있다면 모두 Push하여 서버 상태를 최신으로 맞춘다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;신규 저장소 생성&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;마이그레이션 대상이 될 새로운 Git Server에 레파지토리를 미리 생성해둔다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Step1. 기존 레파지토리 복제 (Mirror Clone)&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;먼저 PC 로컬에 임시 폴더를 생성한뒤&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;기존 Git Server에서 프로젝트의 레파지토리 주소를 복사한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;그 다음 터미널에서 아래 명령어를 입력한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1777015694976&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 모든 커밋 이력과 브랜치를 포함하여 복제
git clone --mirror [기존_Bonobo_레포지토리_URL]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;완료되면 로컬에 [프로젝트명.git] 형태의 폴더가 생성된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이 폴더는 단순 소스뿐만 아니라 모든 커밋 히스토리를 포함하고 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Step2. 신규 서버로 Push (Mirror Push)&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;새로운 Git Server에서 생성한 프로젝트의 URL을 복사한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;그후 방금 생성된 [프로젝트명.git] 폴더 안으로 진입하여 새 서버로 데이터를 밀어넣는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1777015807215&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 생성된 폴더로 진입
cd [프로젝트명.git]

# 새로운 GitLab 서버로 모든 이력 Push
git push --mirror [새로운_GitLab_URL]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;마이그레이션이 완료 되면 새로운 Git Server에 커밋 이력이 정상적으로 옮겨져잇는지 확인한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;*이제 위에서 생성된 [프로젝트명.git] 폴더는 삭제해도 무방하다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Step3. 로컬 설정 변경&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;마지막으로,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;기존에 작업하던 로컬 프로젝트들이 새로운 서버를 바라보도록&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;원격 저장소 주소를 수정해야한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1777015962891&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git remote set-url origin [새로운_GitLab_URL]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git</category>
      <category>BonoboGit</category>
      <category>Git</category>
      <category>Git 마이그레이션</category>
      <category>Git 서버이전</category>
      <category>gitclone</category>
      <category>GitLab</category>
      <category>gitmirror</category>
      <category>Migration</category>
      <category>레파지토리이전</category>
      <category>커밋이력옮기기</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/43</guid>
      <comments>https://sslee92.tistory.com/43#entry43comment</comments>
      <pubDate>Fri, 24 Apr 2026 16:33:59 +0900</pubDate>
    </item>
    <item>
      <title>2026년 바이브코딩(Vibe Coding)을 넘어 에이전틱 코딩(Agentic Coding)의 시대로</title>
      <link>https://sslee92.tistory.com/42</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;i&gt;클로드 코드(Claude Code)&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;i&gt;구글 안티그래비티(Antigravity)&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;i&gt;커서(Cursor)&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ...&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;최근 한번쯤은 들어봤을 이름들이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이글에서는 최근 들려오는 이런 &lt;b&gt;에이전틱 AI&lt;/b&gt;를&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;내가 직접 경험하며 느낀점들 풀어보려고한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt; &lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;b&gt;바이브코딩은 '서막'에 불과했다&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;불과 4개월전 바이브 코딩(Vibe Coding)에 대한 생각을 작성했었다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2025.12.01 - [AI] - 바이브 코딩(Vibe Coding), 이 방식&amp;hellip; 결국 개발자는 뭘 해야 할까?&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1772688145633&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;바이브 코딩(Vibe Coding), 이 방식&amp;hellip; 결국 개발자는 뭘 해야 할까?&quot; data-og-description=&quot;AI가 코드를 대신 작성해주는 &amp;lsquo;바이브 코딩&amp;rsquo;이 빠르게 퍼지면서 개발 방식 전체가 뒤집히는 변화가 오고 있다. 이제 자연어로 설명만 하면 함수도 만들고, 웹페이지도 만들고, 복잡한 프로세&quot; data-og-host=&quot;sslee92.tistory.com&quot; data-og-source-url=&quot;https://sslee92.tistory.com/41&quot; data-og-url=&quot;https://sslee92.tistory.com/41&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/wOnPO/dJMb9eTNrJA/ta4T76sukq8UKoRD8BWgYk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/btDDyv/dJMb83kqHkp/vDsAHRFjKdgOab4kPai6uk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sslee92.tistory.com/41&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/wOnPO/dJMb9eTNrJA/ta4T76sukq8UKoRD8BWgYk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/btDDyv/dJMb83kqHkp/vDsAHRFjKdgOab4kPai6uk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;바이브 코딩(Vibe Coding), 이 방식&amp;hellip; 결국 개발자는 뭘 해야 할까?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AI가 코드를 대신 작성해주는 &amp;lsquo;바이브 코딩&amp;rsquo;이 빠르게 퍼지면서 개발 방식 전체가 뒤집히는 변화가 오고 있다. 이제 자연어로 설명만 하면 함수도 만들고, 웹페이지도 만들고, 복잡한 프로세&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sslee92.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2025년 까지 우리는 AI와 대화하며 코드를 짜는 &lt;i&gt;&lt;b&gt;'바이브 코딩' &lt;/b&gt;&lt;/i&gt;에 열광했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;개발자의 의도를 자연어로 전달하면 AI가 코드를 뱉어내는 방식은 혁명적이였다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2026년 개발 환경은 인공지능의 개입 수준이&lt;br /&gt;설계, 구현, 검증 및 배포 까지에 이르는 과정들을 주도적으로 수행하는&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;'에이전틱 코딩(Agentic Coding)'&lt;/i&gt;&lt;/b&gt; 의 시대로 진입하고 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;i&gt;&lt;b&gt;에이전틱 코딩(Agentic Coding), 무엇이 달라졌나?&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;바이브코딩에서의 개발자는&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AI가 뱉어낸 코드를 IDE에 복사하고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;빌드버튼을 누르고, 에러가 나면 메시지를 긁어 다시 AI에게 묻는&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;수동적 루프를 반복해야 했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;사실상 개발자가 AI와 IDE 사이를 잇는 역할을 했던 셈이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;에이전틱 코딩은 이 루프 자체가 AI 내부로 들어갔다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이제 에이전트 AI는&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;직접 IDE의 컨텍스트를 분석하여 코드의 의도를 파악하고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;수정이 필요한 파일을 찾아 코드를 스스로 작성한 뒤 IDE에 즉시 반영한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 멈추지않는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;터미널을 제어해 빌드를 실행하고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;성공할 때까지 스스로 수정을 반복한 뒤 최종 결과만을 보고한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이제 개발자는&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;'AI가 도출한 결과가 비즈니스 로직에 적합한지 판단하는 사람'&lt;/i&gt; &lt;/b&gt;이 되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;i&gt;&lt;b&gt;도구의 진화, 그리고 변하지 않는 본질&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AI는 여전히 도구일 뿐이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 그 도구의 수준이 이제는 &lt;b&gt;'자율적 수행'&lt;/b&gt;의 단계까지 올라왔다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;도구가 아무리 똑똑해져도 그 결과물에 대한 &lt;b data-index-in-node=&quot;117&quot; data-path-to-node=&quot;10&quot;&gt;최종 승인 권한&lt;/b&gt;은 여전히 우리에게 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;도구가 강력해질수록 그것을 다루는 사람의 판단력과 책임감은 그 어느 때보다 중요해질 것이라 생각한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이제 우리는 단순한 코더를 넘어,&amp;nbsp; 전체 시스템을 조망하고 검증하는&amp;nbsp; 진정한 시스템 설계자로서 이 변화를 맞이해야 할 것이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;</description>
      <category>AI</category>
      <category>agentic ai</category>
      <category>agentic coding</category>
      <category>Antigravity</category>
      <category>claudecode</category>
      <category>cursorai</category>
      <category>vibe coding</category>
      <category>미래기술</category>
      <category>바이브코딩</category>
      <category>에이전틱 ai</category>
      <category>에이전틱 코딩</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/42</guid>
      <comments>https://sslee92.tistory.com/42#entry42comment</comments>
      <pubDate>Thu, 5 Mar 2026 15:25:33 +0900</pubDate>
    </item>
    <item>
      <title>바이브 코딩(Vibe Coding), 이 방식&amp;hellip; 결국 개발자는 뭘 해야 할까?</title>
      <link>https://sslee92.tistory.com/41</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AI가&amp;nbsp;코드를&amp;nbsp;대신&amp;nbsp;작성해주는&amp;nbsp;&amp;lsquo;바이브&amp;nbsp;코딩&amp;rsquo;이&amp;nbsp;빠르게&amp;nbsp;퍼지면서 &lt;br /&gt;개발&amp;nbsp;방식&amp;nbsp;전체가&amp;nbsp;뒤집히는&amp;nbsp;변화가&amp;nbsp;오고&amp;nbsp;있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이제&amp;nbsp;자연어로&amp;nbsp;설명만&amp;nbsp;하면&amp;nbsp;함수도&amp;nbsp;만들고,&amp;nbsp;웹페이지도&amp;nbsp;만들고, &lt;br /&gt;복잡한&amp;nbsp;프로세스까지&amp;nbsp;코드&amp;nbsp;형태로&amp;nbsp;뚝딱&amp;nbsp;만들어준다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;흐름속에&amp;nbsp;여러&amp;nbsp;개발자들은&amp;nbsp;이런&amp;nbsp;궁금증이&amp;nbsp;생겼을&amp;nbsp;것이다. &lt;br /&gt;&lt;i&gt;&lt;b&gt;&quot;그렇다면&amp;nbsp;개발자는&amp;nbsp;이제&amp;nbsp;무엇을&amp;nbsp;해야&amp;nbsp;하는&amp;nbsp;걸까?&quot;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이&amp;nbsp;글에서는&amp;nbsp;바이브&amp;nbsp;코딩&amp;nbsp;자체를&amp;nbsp;설명하기&amp;nbsp;보다는, &lt;br /&gt;이&amp;nbsp;방식&amp;nbsp;속에서&amp;nbsp;개발자가&amp;nbsp;어떤&amp;nbsp;역할을&amp;nbsp;하면&amp;nbsp;좋을지, &lt;br /&gt;그리고&amp;nbsp;내가&amp;nbsp;실제로&amp;nbsp;경험하며&amp;nbsp;느낀&amp;nbsp;점들을&amp;nbsp;중심으로&amp;nbsp;풀어보려고&amp;nbsp;한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt; 바이브&amp;nbsp;코딩&amp;nbsp;시대,&amp;nbsp;결국&amp;nbsp;개발자는&amp;nbsp;무엇을&amp;nbsp;해야&amp;nbsp;할까?&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;바이브코딩은&lt;br /&gt;예전의&amp;nbsp;&lt;b&gt;&lt;i&gt;&amp;ldquo;내가&amp;nbsp;코딩하고&amp;nbsp;AI가&amp;nbsp;돕는다&amp;rdquo;&lt;/i&gt;&lt;/b&gt;에서 &lt;br /&gt;이제는 &lt;b&gt;&lt;i&gt;&amp;ldquo;AI가 코딩하고 내가 돕는다&amp;rdquo;&lt;/i&gt;&lt;/b&gt;로 역할이 완전히 바뀌었다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AI가 코드를 빠르게 만들어주는 시대라고 해서&lt;br /&gt;개발자의 역할이 줄어든 건 절대 아니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;오히려 나는 요즘 들어&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;&quot;개발자는 더 생각하는 사람이 되어야 한다&quot;&lt;/b&gt; &lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;라고 더 강하게 느끼고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;솔직히&amp;nbsp;말해서, &lt;br /&gt;나는&amp;nbsp;생성형&amp;nbsp;인공지능(AI)을&amp;nbsp;완전히&amp;nbsp;신뢰하지는&amp;nbsp;않는다. &lt;br /&gt;AI가&amp;nbsp;만들어주는&amp;nbsp;코드는&amp;nbsp;빠르고&amp;nbsp;편하지만, &lt;br /&gt;그&amp;nbsp;코드가&amp;nbsp;실제&amp;nbsp;의도를&amp;nbsp;제대로&amp;nbsp;반영했는지, &lt;br /&gt;전체&amp;nbsp;구조에&amp;nbsp;문제를&amp;nbsp;만들지는&amp;nbsp;않는지, &lt;br /&gt;장기적으로&amp;nbsp;유지&amp;nbsp;가능한지는&amp;nbsp;아직&amp;nbsp;스스로&amp;nbsp;판단하지&amp;nbsp;못한다. &lt;br /&gt;&lt;br /&gt;그렇지만,&amp;nbsp;그럼에도&amp;nbsp;불구하고 &lt;br /&gt;바이브&amp;nbsp;코딩은&amp;nbsp;이제&amp;nbsp;선택이&amp;nbsp;아니라&amp;nbsp;필수가&amp;nbsp;되어가고&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;주변&amp;nbsp;동료&amp;nbsp;개발자들만&amp;nbsp;봐도 &lt;br /&gt;&lt;i&gt;&lt;b&gt;&amp;ldquo;AI&amp;nbsp;없이는&amp;nbsp;이제&amp;nbsp;코딩&amp;nbsp;못할거같다&amp;rdquo;&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;라고&amp;nbsp;말하는&amp;nbsp;경우가&amp;nbsp;흔해졌고,&amp;nbsp; &lt;br /&gt;그만큼&amp;nbsp;AI의&amp;nbsp;생산성&amp;nbsp;향상&amp;nbsp;효과는&amp;nbsp;명확하고, &lt;br /&gt;이&amp;nbsp;흐름은&amp;nbsp;되돌릴&amp;nbsp;수&amp;nbsp;없는&amp;nbsp;방향이라는&amp;nbsp;뜻이다. &lt;br /&gt;&lt;br /&gt;바이브&amp;nbsp;코딩을&amp;nbsp;피할&amp;nbsp;수&amp;nbsp;없다면, &lt;br /&gt;이&amp;nbsp;흐름&amp;nbsp;안에서&amp;nbsp;개발자가&amp;nbsp;어떤&amp;nbsp;역할을&amp;nbsp;해야&amp;nbsp;하는지를&amp;nbsp;명확하게&amp;nbsp;아는&amp;nbsp;게&amp;nbsp;더&amp;nbsp;중요하다. &lt;br /&gt;그리고&amp;nbsp;내가&amp;nbsp;경험해본&amp;nbsp;개발자의&amp;nbsp;역할은&amp;nbsp;다음과&amp;nbsp;같다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;i&gt;&lt;b&gt; 1. 방향을 제시하는 사람&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AI는 스스로 목표를 설정하지 못한다.&lt;br /&gt;개발자가 정확한 의도와 방향을 던져주지 않으면&lt;br /&gt;AI는 그럴듯하지만 엉뚱한 코드를 만들어낸다.&lt;br /&gt;즉, 개발자는 &lt;i&gt;&lt;b&gt;&quot;무엇을 만들지&quot; 정의하는 책임자 &lt;/b&gt;&lt;/i&gt;가 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  &lt;/b&gt;&lt;i&gt;&lt;b&gt;2. 전체 구조를 판단하는 사람&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AI가 코드를 95% 짜더라도&lt;br /&gt;그 코드가 시스템 전체 흐름과 맞는지는 사람이 판단해야 한다.&lt;br /&gt;특히 네트워크, 스레드, DB, 프로토콜 같은&lt;br /&gt;&lt;i&gt;&lt;b&gt;실제 장애로 직결되는 영역은 반드시 사람이 검토해야 한다.&lt;/b&gt; &lt;/i&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;i&gt;&lt;b&gt;&amp;nbsp; 3. 문제를 발견하는 사람&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AI가 만들어주는 코드는 겉보기엔 그럴듯하지만&lt;br /&gt;디테일한 부분에서 논리적 오류가 숨어 있는 경우가 많다.&lt;br /&gt;이걸 발견할 수 있는 건 결국 &lt;i&gt;&lt;b&gt;코드의 의미를 읽을 줄 아는 사람&lt;/b&gt;&lt;/i&gt;,&lt;br /&gt;즉 개발자뿐이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;i&gt;&lt;b&gt; 정리하자면 &lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;바이브 코딩은 이제 새로운 유행이 아니라,&lt;br /&gt;개발 방식의 하나의 표준으로 자리 잡아가고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 AI가 코드를 대신 짠다고 해서&lt;br /&gt;개발자가 할 일이 줄어드는 건 아니다.&lt;br /&gt;오히려 개발자는 &lt;i&gt;&lt;b&gt;더 생각하고, 판단하고, 검증하는 역할&lt;/b&gt;&lt;/i&gt;을 맡게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;1371&quot; data-start=&quot;1246&quot; data-ke-size=&quot;size16&quot;&gt;나는 AI를 100% 믿지는 않지만,&lt;br /&gt;그래도 바이브 코딩의 흐름은 분명하게 다가오고 있다.&lt;br /&gt;그렇다면 우리는 이 흐름을 거부하는 것이 아니라,&lt;br /&gt;그 안에서 &lt;i&gt;&lt;b&gt;내 역할을 확실하게 가져가는 것&lt;/b&gt;&lt;/i&gt;이 중요하다고 생각한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;1426&quot; data-start=&quot;1373&quot; data-ke-size=&quot;size16&quot;&gt;AI는 코드를 만들어주는 도구이고,&lt;br /&gt;그 코드의 &lt;i&gt;&lt;b&gt;의미와 책임은 여전히 개발자의 몫&lt;/b&gt;&lt;/i&gt;이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h1 style=&quot;text-align: center;&quot; data-end=&quot;185&quot; data-start=&quot;158&quot;&gt;&lt;b&gt;  &lt;/b&gt;&lt;i&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/i&gt;&lt;/h1&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;257&quot; data-start=&quot;187&quot; data-ke-size=&quot;size16&quot;&gt;결국 바이브 코딩은&lt;br /&gt;&amp;ldquo;AI가 코드를 작성하는 방식&amp;rdquo;이 아니라&lt;br /&gt;&lt;i&gt;&lt;b&gt;&amp;ldquo;개발자가 AI와 함께 일하는 방식&amp;rdquo;&lt;/b&gt;&lt;/i&gt;의 변화라고 생각한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;257&quot; data-start=&quot;187&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;362&quot; data-start=&quot;259&quot; data-ke-size=&quot;size16&quot;&gt;코드를 누가 먼저 치느냐가 중요한 게 아니라,&lt;br /&gt;&lt;b&gt;그 코드가 진짜로 문제를 해결하는지 판단하는 능력&lt;/b&gt;,&lt;br /&gt;그리고 &lt;b&gt;시스템의 방향을 잡아주는 통찰력&lt;/b&gt;이 더 중요한 시대가 왔다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;362&quot; data-start=&quot;259&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;437&quot; data-start=&quot;364&quot; data-ke-size=&quot;size16&quot;&gt;앞으로 AI는 더 똑똑해지고, 더 많은 역할을 대신하게 될 것이다.&lt;br /&gt;하지만 그 변화 속에서 우리가 놓치지 말아야 할 건 하나다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;437&quot; data-start=&quot;364&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;494&quot; data-start=&quot;439&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;AI가 코드를 만들 수는 있어도,&lt;br /&gt;무엇을 만들어야 하는지는 여전히 사람이 결정한다는 것.&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;494&quot; data-start=&quot;439&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;574&quot; data-start=&quot;496&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나는 앞으로도&lt;br /&gt;AI를 도구로 활용하되 맹신하지 않고,&lt;br /&gt;AI가 만들어낸 결과를 스스로 판단할 수 있는 능력을 더 키우려고 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;574&quot; data-start=&quot;496&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;645&quot; data-start=&quot;576&quot; data-ke-size=&quot;size16&quot;&gt;바이브 코딩은 선택이 아닌 필수지만,&lt;br /&gt;그 흐름 속에서 &lt;i&gt;&lt;b&gt;개발자의 가치는 오히려 더 중요해지는 시대&lt;/b&gt;&lt;/i&gt;라고 나는 믿는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;645&quot; data-start=&quot;576&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;645&quot; data-start=&quot;576&quot; data-ke-size=&quot;size16&quot;&gt;모든 개발자들, 오늘도 화이팅.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI</category>
      <category>AI</category>
      <category>ai코딩</category>
      <category>vibecoding</category>
      <category>바이브코더</category>
      <category>바이브코딩</category>
      <category>생성형인공지능</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/41</guid>
      <comments>https://sslee92.tistory.com/41#entry41comment</comments>
      <pubDate>Mon, 1 Dec 2025 15:50:13 +0900</pubDate>
    </item>
    <item>
      <title>[오류 / WPF / MediaPlayer] WPF MediaPlayer에서 &amp;quot;Windows Media Player 버전 10 이상이 필요합니다.&amp;quot; 오류 해결법</title>
      <link>https://sslee92.tistory.com/40</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;오류내용&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;오류원인&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;해결방법&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;오류내용&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #ef5369; background-color: #f6e199;&quot;&gt;&lt;i&gt;&lt;b&gt; &lt;span style=&quot;text-align: left;&quot;&gt;&quot;Windows Media Player 10 이상이 필요합니다.&quot;&amp;nbsp;&lt;/span&gt; &lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Windows 11 환경에서 mp3 파일을 직접 실행하는&amp;nbsp;경우에는 정상적으로 소리가 재생된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 아래와 같이 C# WPF 프로그램에서 MediaPlayer로 mp3 파일을 재생하려고 하면,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아무런 소리가 나지 않는 현상&lt;/b&gt;이 발생했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753776678401&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private MediaPlayer _mediaPlayer;

private void PlaySound()
{
    try
    {
        string mp3FilePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, &quot;Sound.mp3&quot;);

        // 파일이 존재하는지 확인
        if (!System.IO.File.Exists(mp3FilePath))
        {
            LogHelper.Instance.WriteLog(&quot;mp3파일이 존재하지 않습니다.&quot;, true);
            return;
        }

        var mediaPlayer = new MediaPlayer(); // 지역 변수로 선언
        mediaPlayer.Volume = 1.0; // 볼륨 100%

        // 미디어 파일 열리면 바로 재생
        mediaPlayer.MediaOpened += (s, e) =&amp;gt; mediaPlayer.Play();

        // 오류 발생 시 로그 기록
        mediaPlayer.MediaFailed += (s, e) =&amp;gt;
            LogHelper.Instance.WriteLog(&quot;MediaPlayer 오류: &quot; + e.ErrorException.Message, true);

        // mp3 파일 열기
        mediaPlayer.Open(new Uri(mp3FilePath));
    }
    catch (Exception ex)
    {
        LogHelper.Instance.WriteException(ex);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;오류원인&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;이 문제는 Windows 11의 &amp;ldquo;미디어 기능&amp;rdquo;이 비활성화되어 있었기 때문이었다.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;- Windows 11 Pro, Education, N/KN 등 일부 버전에서는 &lt;br /&gt;&amp;nbsp;기본적으로 Windows Media Player 및 관련 미디어 재생 기능(코덱 포함)이 설치되어 있지 않거나, 꺼져있는 경우가 있다. &lt;br /&gt;&lt;br /&gt;- WPF의 MediaPlayer는 내부적으로 Windows Media Foundation(혹은 Windows Media Player)을 활용해서&lt;br /&gt;&amp;nbsp;mp3, wma, wav 등 미디어 파일을 재생한다. &lt;br /&gt;&amp;nbsp; &amp;rarr; 따라서 미디어 재생 관련 Windows 구성 요소가 꺼져 있으면, 코드상으로 아무 오류도 발생하지 않거나, &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 또는 &quot;Windows Media Player 10 이상이 필요합니다.&quot; 같은 메시지가 발생하면서 mp3 재생이 아예 안된다. &lt;br /&gt;&lt;br /&gt;- 파일 자체에는 이상이 없고, 탐색기에서 직접 실행할 때는 다른 코덱이나 앱(예: Groove 음악, VLC 등)이 대신 재생해서&amp;nbsp; &amp;nbsp; 정상 동작하는 것처럼 보일 수 있다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;오류 해결방법&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;실행(Win+R)에서 &lt;b&gt;optionalfeatures&lt;/b&gt; 입력 후&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래 이미지에 표시된&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;[Windows Media Player 레거시(앱)] 을 체크해주면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;907&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIjhu4/btsPBfA7sct/81eFdiQAVOYUWLLsy7uJkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIjhu4/btsPBfA7sct/81eFdiQAVOYUWLLsy7uJkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIjhu4/btsPBfA7sct/81eFdiQAVOYUWLLsy7uJkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIjhu4%2FbtsPBfA7sct%2F81eFdiQAVOYUWLLsy7uJkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;429&quot; height=&quot;907&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;907&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;</description>
      <category>c#/오류</category>
      <category>MediaPlayer play 안됨</category>
      <category>MediaPlayer 에러</category>
      <category>MediaPlayer 오류</category>
      <category>Windows Media Player 버전 10 이상이 필요합니다</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/40</guid>
      <comments>https://sslee92.tistory.com/40#entry40comment</comments>
      <pubDate>Tue, 29 Jul 2025 17:12:22 +0900</pubDate>
    </item>
    <item>
      <title>[Android / Kotlin] (2) 안드로이드에서 시리얼포트 통신하기 (android-serialport-api 오픈소스)</title>
      <link>https://sslee92.tistory.com/39</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;이전 블로그&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/38&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2025.07.08 - [분류 전체보기] - [ Android / Kotlin ] (1) 안드로이드에서 시리얼포트 통신하기 (android-serialport-api 오픈소스)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1751937965369&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ Android / Kotlin ] (1) 안드로이드에서 시리얼포트 통신하기 (android-serialport-api 오픈소스)&quot; data-og-description=&quot;&quot; data-og-host=&quot;sslee92.tistory.com&quot; data-og-source-url=&quot;https://sslee92.tistory.com/38&quot; data-og-url=&quot;https://sslee92.tistory.com/38&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/38&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sslee92.tistory.com/38&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[ Android / Kotlin ] (1) 안드로이드에서 시리얼포트 통신하기 (android-serialport-api 오픈소스)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sslee92.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;시리얼 통신 코드 예제&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1751938080344&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import android.util.Log
import java.io.File
import java.io.InputStream
import java.io.OutputStream
import android_serialport_api.SerialPort
import kotlin.concurrent.thread

class SerialPortManager(
    private val devicePath: String,   // 예: &quot;/dev/ttyS1&quot;
    private val baudRate: Int         // 예: 115200
) {
    private var serialPort: SerialPort? = null
    private var inputStream: InputStream? = null
    private var outputStream: OutputStream? = null

    var isListening = false

    // 시리얼 포트 열기
    fun open(): Boolean {
        return try {
            val device = File(devicePath)
            serialPort = SerialPort(device, baudRate, 0)
            inputStream = serialPort?.inputStream
            outputStream = serialPort?.outputStream
            Log.d(&quot;SerialPortManager&quot;, &quot;Serial port opened: $devicePath at $baudRate&quot;)
            true
        } catch (e: Exception) {
            Log.e(&quot;SerialPortManager&quot;, &quot;Failed to open serial port: ${e.message}&quot;, e)
            false
        }
    }

    // 명령어 전송
    fun send(command: String) {
        try {
            outputStream?.write(command.toByteArray())
            outputStream?.flush()
        } catch (e: Exception) {
            Log.e(&quot;SerialPortManager&quot;, &quot;Send error: ${e.message}&quot;, e)
        }
    }

    // 포트 닫기
    fun close() {
        isListening = false
        inputStream?.close()
        outputStream?.close()
        serialPort = null
    }

    // 비동기로 데이터 수신 (콜백 방식)
    fun listen(callback: (String) -&amp;gt; Unit) {
        isListening = true
        thread(start = true) {
            val buffer = ByteArray(64)
            while (isListening) {
                try {
                    val size = inputStream?.read(buffer) ?: break
                    if (size &amp;gt; 0) {
                        val data = String(buffer, 0, size)
                        callback(data)
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    break
                }
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;사용예제&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1751938108972&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val serial = SerialPortManager(&quot;/dev/ttyS1&quot;, 115200)

if (serial.open()) {
    // 데이터 수신(콜백)
    serial.listen { data -&amp;gt;
        Log.d(&quot;SerialTest&quot;, &quot;수신 데이터: $data&quot;)
    }
    
    // 명령 전송
    serial.send(&quot;message&quot;)

    // ... 필요시 close()
    // serial.close()
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>android serial</category>
      <category>안드로이드 시리얼통신</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/39</guid>
      <comments>https://sslee92.tistory.com/39#entry39comment</comments>
      <pubDate>Tue, 8 Jul 2025 10:25:28 +0900</pubDate>
    </item>
    <item>
      <title>[Android / Kotlin] (1) 안드로이드에서 시리얼포트 통신하기 (android-serialport-api 오픈소스)</title>
      <link>https://sslee92.tistory.com/38</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드 보드에서 외부 컨트롤보드와 RS232 시리얼 통신이 필요해서&lt;br /&gt;시리얼 통신 구현 방법을 정리해봤다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;일단, &lt;b&gt;안드로이드 기본 SDK에는 시리얼 포트를 직접 제어할 수 있는 API가 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;277&quot; data-start=&quot;195&quot; data-ke-size=&quot;size16&quot;&gt;그래서 시리얼 포트 통신을 위해 별도의 라이브러리가 필요한데,&lt;br /&gt;이때 많이 사용하는 것이 바로 &lt;b&gt;android-serialport-api&lt;/b&gt;다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;277&quot; data-start=&quot;195&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;412&quot; data-start=&quot;279&quot; data-ke-size=&quot;size16&quot;&gt;이 라이브러리는&lt;br /&gt;&lt;b&gt;JNI(Java Native Interface)&lt;/b&gt;와 &lt;b&gt;C&lt;/b&gt; 코드를 활용해서&lt;br /&gt;리눅스 커널이 제공하는&lt;b&gt; /dev/ttyS*, /dev/ttyUSB*&lt;/b&gt; 같은 시리얼 포트와&lt;br /&gt;안드로이드 앱에서 직접 통신할 수 있게 해준다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;1. android-serialport-api 오픈소스 다운&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/cepr/android-serialport-api&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/cepr/android-serialport-api&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1751933880300&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - cepr/android-serialport-api: Accessing serial ports for Android&quot; data-og-description=&quot;Accessing serial ports for Android. Contribute to cepr/android-serialport-api development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/cepr/android-serialport-api&quot; data-og-url=&quot;https://github.com/cepr/android-serialport-api&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1d5dw/hyZjv6rVIO/CE01SDUFg2krdb51N8FBMk/img.png?width=1200&amp;amp;height=600&amp;amp;face=956_180_1006_236,https://scrap.kakaocdn.net/dn/ikcxS/hyZjg9gfBP/KcZiKkZcOMpVHLBPhyfLQK/img.png?width=1200&amp;amp;height=600&amp;amp;face=956_180_1006_236&quot;&gt;&lt;a href=&quot;https://github.com/cepr/android-serialport-api&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/cepr/android-serialport-api&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1d5dw/hyZjv6rVIO/CE01SDUFg2krdb51N8FBMk/img.png?width=1200&amp;amp;height=600&amp;amp;face=956_180_1006_236,https://scrap.kakaocdn.net/dn/ikcxS/hyZjg9gfBP/KcZiKkZcOMpVHLBPhyfLQK/img.png?width=1200&amp;amp;height=600&amp;amp;face=956_180_1006_236');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - cepr/android-serialport-api: Accessing serial ports for Android&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Accessing serial ports for Android. Contribute to cepr/android-serialport-api development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;144&quot; data-start=&quot;35&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;android-serialport-api&lt;/b&gt; 라이브러리를 다운로드해서 압축을 풀면&lt;br /&gt;&lt;b&gt;android-sercd&lt;/b&gt; 폴더와 &lt;b&gt;android-serialport-api&lt;/b&gt; 폴더, 두 개가 생성된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;196&quot; data-start=&quot;146&quot; data-ke-size=&quot;size16&quot;&gt;여기서 실제로 사용하는 것은 &lt;b&gt;android-serialport-api&lt;/b&gt; 폴더 하나다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;196&quot; data-start=&quot;146&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;293&quot; data-start=&quot;198&quot; data-ke-size=&quot;size16&quot;&gt;이 폴더 안으로 들어가면,&lt;br /&gt;&lt;b&gt;project&lt;/b&gt;라는 하위 폴더가 있고,&lt;br /&gt;그 안에는 &lt;b&gt;jni&lt;/b&gt;, &lt;b&gt;libs&lt;/b&gt;, &lt;b&gt;res&lt;/b&gt;, &lt;b&gt;src&lt;/b&gt; 폴더가 존재한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;372&quot; data-start=&quot;295&quot; data-ke-size=&quot;size16&quot;&gt;이 중에서 &lt;b&gt;src&lt;/b&gt; 폴더에 들어가보면&lt;br /&gt;여기에도 다시 &lt;b&gt;android-serialport-api&lt;/b&gt;라는 폴더가 한 번 더 나온다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;2. 프로젝트 생성 및 폴더 복사&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;142&quot; data-start=&quot;45&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트를 새로 생성한 후,&lt;br /&gt;&lt;b&gt;프로젝트 폴더의 src &amp;rarr; main &amp;rarr; java&lt;/b&gt; 경로 아래에&lt;br /&gt;&lt;b&gt;android-serialport-api&lt;/b&gt; 폴더를 복사해 넣는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;142&quot; data-start=&quot;45&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;218&quot; data-start=&quot;144&quot; data-ke-size=&quot;size16&quot;&gt;여기서 복사하는 &lt;b&gt;android-serialport-api&lt;/b&gt; 폴더는&lt;br /&gt;압축을 풀었을 때&lt;b&gt; src&lt;/b&gt; 내부에 있던 폴더를 의미한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;257&quot; data-start=&quot;220&quot; data-ke-size=&quot;size16&quot;&gt;그리고 예제 코드가 들어있는 &lt;b&gt;sample&lt;/b&gt; 폴더는 삭제해도 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;288&quot; data-start=&quot;259&quot; data-ke-size=&quot;size16&quot;&gt;여기까지 진행하면 폴더 구조는 아래와 같이 정리된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JYpv8/btsO7fVXwIA/waAqTy6XA6uDIU2epbBJVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JYpv8/btsO7fVXwIA/waAqTy6XA6uDIU2epbBJVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JYpv8/btsO7fVXwIA/waAqTy6XA6uDIU2epbBJVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJYpv8%2FbtsO7fVXwIA%2FwaAqTy6XA6uDIU2epbBJVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;413&quot; height=&quot;318&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;144&quot; data-start=&quot;31&quot; data-ke-size=&quot;size16&quot;&gt;그리고, 압축을 해제한 소스 중에서&lt;br /&gt;&lt;b&gt;project&lt;/b&gt; 폴더 하위에 있던 &lt;b&gt;jni &lt;/b&gt;폴더와 &lt;b&gt;libs&lt;/b&gt; 폴더를&lt;br /&gt;안드로이드 프로젝트의 &lt;b&gt;app &amp;rarr; src &amp;rarr; main&lt;/b&gt; 폴더 아래에 복사해서 붙여넣는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;144&quot; data-start=&quot;31&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;202&quot; data-start=&quot;146&quot; data-ke-size=&quot;size16&quot;&gt;이 과정을 거치면,&lt;br /&gt;&lt;b&gt;cpp&lt;/b&gt; 폴더가 새로 생성된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;409&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/szJrN/btsO8CI7mMS/IbhC8hlREkVu9w6swZ8TK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/szJrN/btsO8CI7mMS/IbhC8hlREkVu9w6swZ8TK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/szJrN/btsO8CI7mMS/IbhC8hlREkVu9w6swZ8TK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FszJrN%2FbtsO8CI7mMS%2FIbhC8hlREkVu9w6swZ8TK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;644&quot; height=&quot;409&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;409&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;3. NDK, CMake 설치&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;97&quot; data-start=&quot;29&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Tools&lt;/b&gt; 메뉴에서 &lt;b&gt;SDK Manager&lt;/b&gt;를 선택한 뒤,&lt;br /&gt;상단의 &lt;b&gt;SDK Tools&lt;/b&gt; 탭으로 이동한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;146&quot; data-start=&quot;99&quot; data-ke-size=&quot;size16&quot;&gt;그리고 아래 이미지처럼 &lt;b&gt;NDK&lt;/b&gt;와 &lt;b&gt;CMake&lt;/b&gt; 항목을 체크해서 설치해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;737&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bukQPv/btsO8U3Gn1A/6N2VkJCejXo3GAXa3Y9YmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bukQPv/btsO8U3Gn1A/6N2VkJCejXo3GAXa3Y9YmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bukQPv/btsO8U3Gn1A/6N2VkJCejXo3GAXa3Y9YmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbukQPv%2FbtsO8U3Gn1A%2F6N2VkJCejXo3GAXa3Y9YmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;985&quot; height=&quot;737&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;737&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;192&quot; data-start=&quot;61&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 &lt;b&gt;NDK&lt;/b&gt;와 &lt;b&gt;CMake&lt;/b&gt;를 설치하는 이유는&lt;br /&gt;&lt;b&gt;android-serialport-api&lt;/b&gt;가 &lt;b&gt;JNI(Java Native Interface)&lt;/b&gt; 방식으로&lt;br /&gt;네이티브 C 코드(.so 라이브러리)를 사용하기 때문이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;354&quot; data-start=&quot;194&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드 스튜디오에서 &lt;b&gt;JNI&lt;/b&gt; 연동 및 네이티브 코드 컴파일을 하려면&lt;br /&gt;&lt;b&gt;NDK(Native Development Kit) &lt;/b&gt;와 &lt;b&gt;CMake&lt;/b&gt;가 반드시 필요하다.&lt;br /&gt;이 두 가지가 설치되어 있어야&lt;br /&gt;프로젝트를 빌드할 때 네이티브 라이브러리를 정상적으로 인식하고 사용할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;4. Add C++ to Module로 JNI 연동 설정하기 &lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;100&quot; data-start=&quot;34&quot; data-ke-size=&quot;size16&quot;&gt;이제 안드로이드 스튜디오에서 &lt;b&gt;프로젝트를 우클릭&lt;/b&gt;한 뒤&lt;br /&gt;&lt;b&gt;Add C++ to Module&lt;/b&gt; 메뉴를 선택한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;182&quot; data-start=&quot;102&quot; data-ke-size=&quot;size16&quot;&gt;이후 나오는 창에서&lt;br /&gt;두 번째 라디오버튼을 선택하고,&lt;br /&gt;아까 복사해둔 jni 폴더 경로에서 &lt;b&gt;Android.mk&lt;/b&gt; 파일을 지정해준다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 하면 프로젝트에 네이티브(C/C++) 코드가 정상적으로 연동된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;135&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMiBlx/btsO740s85V/NWVyWbBjlAu5YCLOViNMDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMiBlx/btsO740s85V/NWVyWbBjlAu5YCLOViNMDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMiBlx/btsO740s85V/NWVyWbBjlAu5YCLOViNMDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMiBlx%2FbtsO740s85V%2FNWVyWbBjlAu5YCLOViNMDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;395&quot; height=&quot;135&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;135&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vUlF5/btsO8YEWJAF/Yy6EL8OHfc5qN2fFda3vf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vUlF5/btsO8YEWJAF/Yy6EL8OHfc5qN2fFda3vf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vUlF5/btsO8YEWJAF/Yy6EL8OHfc5qN2fFda3vf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvUlF5%2FbtsO8YEWJAF%2FYy6EL8OHfc5qN2fFda3vf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;553&quot; height=&quot;305&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 과정을 통해&lt;/b&gt;&lt;br /&gt;&lt;b&gt;안드로이드에서 시리얼 포트(UART, RS232 등)를 이용한 통신을 구현할 수 있다. &lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 실제 시리얼 통신 코드 예제와 자세한 사용 방법은&lt;/b&gt;&lt;br /&gt;&lt;b&gt;다음 블로그 글을 참고하면 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/39&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2025.07.08 - [Android/Kotlin] - [Android / Kotlin] (2) 안드로이드에서 시리얼포트 통신하기 (android-serialport-api 오픈소스)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1752217890101&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Android / Kotlin] (2) 안드로이드에서 시리얼포트 통신하기 (android-serialport-api 오픈소스)&quot; data-og-description=&quot;이전 블로그2025.07.08 - [분류 전체보기] - [ Android / Kotlin ] (1) 안드로이드에서 시리얼포트 통신하기 (android-serialport-api 오픈소스) [ Android / Kotlin ] (1) 안드로이드에서 시리얼포트 통신하기 (android-seri&quot; data-og-host=&quot;sslee92.tistory.com&quot; data-og-source-url=&quot;https://sslee92.tistory.com/39&quot; data-og-url=&quot;https://sslee92.tistory.com/39&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c46U8g/hyZjqklXSF/cTyn2gkbULqyiUtNiHglZK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/baU2uh/hyZjm9YMXR/F8ffrwZZjhVVnWuisgJO6k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/39&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sslee92.tistory.com/39&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c46U8g/hyZjqklXSF/cTyn2gkbULqyiUtNiHglZK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/baU2uh/hyZjm9YMXR/F8ffrwZZjhVVnWuisgJO6k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Android / Kotlin] (2) 안드로이드에서 시리얼포트 통신하기 (android-serialport-api 오픈소스)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이전 블로그2025.07.08 - [분류 전체보기] - [ Android / Kotlin ] (1) 안드로이드에서 시리얼포트 통신하기 (android-serialport-api 오픈소스) [ Android / Kotlin ] (1) 안드로이드에서 시리얼포트 통신하기 (android-seri&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sslee92.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>Android</category>
      <category>android serial</category>
      <category>android serial open</category>
      <category>android-serialport-api</category>
      <category>Kotlin</category>
      <category>안드로이드 시리얼 통신</category>
      <category>코틀린 시리얼 통신</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/38</guid>
      <comments>https://sslee92.tistory.com/38#entry38comment</comments>
      <pubDate>Tue, 8 Jul 2025 09:44:10 +0900</pubDate>
    </item>
    <item>
      <title>[Android / Kotlin] Empty Activity와 Empty Views Activity / 안드로이드 버전 선택</title>
      <link>https://sslee92.tistory.com/37</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;코틀린으로 안드로이드를 개발 할 기회가 생겨&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;개발하기 전 안드로이드 프로젝트를 생성하는 시점에 궁금했던 부분을 정리하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;Empty Activity 와 Empty Views Activity 차이&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;안드로이드 버전 선택&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Empty Activity 와 Empty Views Activity 차이&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드 스튜디오를 설치 후&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;New Project&lt;/b&gt;를 하게되면 가장 처음으로 &lt;b&gt;Activity&lt;/b&gt;를 선택하게 된다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;Activity란?&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;안드로이드 4대 구성요소 중 하나로, 앱의 화면을 담당하는 기본 구성요소&lt;/i&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;657&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhAlaY/btsMAZHOQRu/0ZxKopTApylw8v7f3tpWv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhAlaY/btsMAZHOQRu/0ZxKopTApylw8v7f3tpWv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhAlaY/btsMAZHOQRu/0ZxKopTApylw8v7f3tpWv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhAlaY%2FbtsMAZHOQRu%2F0ZxKopTApylw8v7f3tpWv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;496&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;657&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여기서&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Empty Activity&lt;/b&gt;와 &lt;b&gt;Empty Views Activity&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 기본 구성요소만 가지고있는&lt;b&gt; Activity&lt;/b&gt;가 두개가 있다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;처음 구글링을하며 프로젝트 생성을 따라해봤을때&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Empty Acitivity&lt;/b&gt;로 생성하면 &lt;b&gt;layout &lt;/b&gt;폴더 안에&amp;nbsp;&lt;b&gt;activity_main.xml&lt;/b&gt;이 생성되지 않았다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;b&gt;(layout 폴더조차 만들어지지 않음)&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그러다 눈에 들어온 &lt;b&gt;Empty Views Activity&lt;/b&gt;를 선택 후 생성해보니&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;activity_main.xml&lt;/b&gt;이 생성되었다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;찾아보니 둘의 차이점은 &lt;b&gt;Jetpack Compose&lt;/b&gt;의 사용 여부였다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt; &lt;b&gt;Jetpack Compose&lt;/b&gt;&lt;span style=&quot;background-color: #fcfcfc; text-align: left;&quot;&gt;를 한줄로 요약하자면&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;b&gt;XML&lt;/b&gt;&lt;span style=&quot;background-color: #fcfcfc; text-align: left;&quot;&gt;&amp;nbsp;없이&amp;nbsp;&lt;/span&gt;&lt;b&gt;Kotlin&lt;/b&gt;&lt;span style=&quot;background-color: #fcfcfc; text-align: left;&quot;&gt;&amp;nbsp;코드만으로&amp;nbsp;&lt;/span&gt;&lt;b&gt;UI&lt;/b&gt;&lt;span style=&quot;background-color: #fcfcfc; text-align: left;&quot;&gt;를 선언적으로 구성하는 최신 안도르이드&amp;nbsp;&lt;/span&gt;&lt;b&gt;UI&lt;/b&gt;&lt;b&gt;프레임워크&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;span style=&quot;background-color: #fcfcfc; text-align: left;&quot;&gt;정도로 생각하면 될거같다&lt;/span&gt; &lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;b&gt; Empty Activity&lt;/b&gt;로 프로젝트를 생성하게 되면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Jetpack Compose&lt;/b&gt; 기반의 프로젝트로서 &lt;b&gt;XML&lt;/b&gt; 없이 화면을 직접 구성해야 하는것이다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;b&gt;아직 개발을 시작하지 않은 시점이긴 하지만&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;&lt;i&gt;xaml에 UI를 구성하여 코딩하는 닷넷에 익숙해져있는 나로서는&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;&lt;i&gt;비하인드 코드에 컨트롤을 직접 만드는 느낌이라 거부감이 든다...&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;&lt;i&gt;이게 왜 최신 방식인지는 차차 개발하면서 직접 느껴봐야 할거같다&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;찾아본 내용을 전체적으로 정리하자면 아래와같다&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt; 1. Empty Activity&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;- Jetpack Compose를 기반으로 한 최신 방식.&lt;br /&gt;&amp;nbsp;- XML 레이아웃 파일 없이 Composable 함수로 UI를 구성함.&lt;br /&gt;&amp;nbsp;- MainActivity 내부에서 setContent {}를 사용하여 화면을 직접 그리는 방식.&lt;br /&gt;&amp;nbsp;- onCreate() 안에서 setContent {} 내에 Composable 함수를 호출하여 UI를 설정함.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;2. Empty View Activity&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;- 기존의 XML 기반 UI를 사용하는 전통적인 안드로이드 개발 방식.&lt;br /&gt;&amp;nbsp;- activity_main.xml 파일이 생성되고, setContentView(R.layout.activity_main)을 통해 UI를 설정함.&lt;br /&gt;&amp;nbsp;- MainActivity 클래스는 기본적으로 AppCompatActivity를 상속받음.&lt;br /&gt;&amp;nbsp;- findViewById() 또는 View Binding, Data Binding을 이용해 UI 요소에 접근함.&lt;br /&gt;&lt;br /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 82.9208%; height: 152px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 18.9769%; height: 22px;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 28.6192%; height: 22px;&quot;&gt;Empty Activity&lt;/td&gt;
&lt;td style=&quot;width: 35.419%; height: 22px;&quot;&gt;&lt;span style=&quot;background-color: #9b9b9b; color: #ffffff; text-align: left;&quot;&gt;Empty View Activity&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 26px;&quot;&gt;
&lt;td style=&quot;width: 18.9769%; height: 26px;&quot;&gt;UI 시스템&lt;/td&gt;
&lt;td style=&quot;width: 28.6192%; height: 26px;&quot;&gt;Jetpack Compose&lt;/td&gt;
&lt;td style=&quot;width: 35.419%; height: 26px;&quot;&gt;XML 기반 (View)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 26px;&quot;&gt;
&lt;td style=&quot;width: 18.9769%; height: 26px;&quot;&gt;레이아웃 파일&lt;/td&gt;
&lt;td style=&quot;width: 28.6192%; height: 26px;&quot;&gt;없음 (Compose 사용)&lt;/td&gt;
&lt;td style=&quot;width: 35.419%; height: 26px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #666666; text-align: left;&quot;&gt;activity_main.xml 사용&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 26px;&quot;&gt;
&lt;td style=&quot;width: 18.9769%; height: 26px;&quot;&gt;UI 설정 방식&lt;/td&gt;
&lt;td style=&quot;width: 28.6192%; height: 26px;&quot;&gt;setcontent{} 사용&lt;/td&gt;
&lt;td style=&quot;width: 35.419%; height: 26px;&quot;&gt;setContentView(R.layout.activit_main)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 26px;&quot;&gt;
&lt;td style=&quot;width: 18.9769%; height: 26px;&quot;&gt;UI 접근 요소&lt;/td&gt;
&lt;td style=&quot;width: 28.6192%; height: 26px;&quot;&gt;@Composable 함수 활용&lt;/td&gt;
&lt;td style=&quot;width: 35.419%; height: 26px;&quot;&gt;findViewById(), View Binding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 26px;&quot;&gt;
&lt;td style=&quot;width: 18.9769%; height: 26px;&quot;&gt;사용 시점&lt;/td&gt;
&lt;td style=&quot;width: 28.6192%; height: 26px;&quot;&gt;JetPack Compose 프로젝트&lt;/td&gt;
&lt;td style=&quot;width: 35.419%; height: 26px;&quot;&gt;기존 View 시스템 유지&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;안드로이드 버전 선택&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Activity&lt;/b&gt;를 선택후 다음으로 넘어가게 되면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래와같이 프로젝트명, 패키지명 등을 작성하는 화면이 나온다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 &lt;b&gt;Minimum SDK&lt;/b&gt; 항목이 있는데&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드를 처음보는 나는 뭐가뭔지 알수가없어서&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;찾아본 내용을 정리해 보았다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;b&gt;프로젝트생성을 구글링해서 찾아보면 전부다 Lollipop으로 생성하는 예제만 있었음..&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;660&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xUSGV/btsMC8v720W/mkJPuDi9XTjKbx0L4WHebk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xUSGV/btsMC8v720W/mkJPuDi9XTjKbx0L4WHebk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xUSGV/btsMC8v720W/mkJPuDi9XTjKbx0L4WHebk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxUSGV%2FbtsMC8v720W%2FmkJPuDi9XTjKbx0L4WHebk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;908&quot; height=&quot;660&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;660&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Lollipop, Mashmallow, Nougat, Oreo&lt;/b&gt; 등과 같은 이름들은&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드 운영체제의 버전 코드명이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드는 특정 버전마다 달달한 디저트 이름을 코드명으로 사용했고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드10 부터는 코드명을 사용하지 않고 숫자로만 표기한다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;찾아보니 코드명이 없는것은 아닌거같다&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;i&gt;&lt;b&gt;안드로이드 버전에 따른 코드명&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 55.8149%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;코드명&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;버전&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;출시년도&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Cupcake&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;1.5&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2009&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Donut&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;1.6&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;2009&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Eclair&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;2.0 ~ 2.1&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;2009&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Froyo&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;2.2&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2010&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Gingerbread&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;2.3&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;2010&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Honeycomb&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;3.0 ~ 3.2&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2011&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Ice Cream Sandwich&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;4.0&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;2011&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Jelly Bean&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;4.1 ~ 4.3&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2012&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;KitKat&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;4.0&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2013&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Lollipop&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;5.0 ~ 5.1&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2014&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Marshmallow&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;6.0&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2015&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Nougat&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;7.0 ~ 7.1&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2016&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Oreo&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;8.0 ~ 8.1&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2017&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Pie&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;9.0&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2018&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Android 10 (Quince Tart)&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2019&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Android 11 (Red Velvet Cake)&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;11&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Android 12 (Snow Cone)&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2021&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Android 13 (Tiramisu)&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;13&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2022&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Android 14 (UpsideDownCake )&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;14&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2023&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.1055%;&quot;&gt;Android 15 (Vanilla Ice Cream)&lt;/td&gt;
&lt;td style=&quot;width: 11.7987%; text-align: center;&quot;&gt;15&lt;/td&gt;
&lt;td style=&quot;width: 9.63679%;&quot;&gt;2024&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;API 21, API 22&lt;/b&gt; 처럼 &lt;b&gt;API&lt;/b&gt; 뒤에 붙는 숫자는 &lt;b&gt;API Level&lt;/b&gt; 이다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;API Level&lt;/b&gt; 별로 작동되는 코드가 있고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;새로 추가된 코드가 있거나 더이상 사용할 수 없는 코드도 있다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;API Level&lt;/b&gt;이 높을수록 새로운 기능과 변경된 &lt;b&gt;API&lt;/b&gt;를 포함한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>empty activity</category>
      <category>empty activity empty views activity 차이</category>
      <category>empty activity 와 empty views activity 차이</category>
      <category>empty vies activity</category>
      <category>안드로이드</category>
      <category>안드로이드 시작하기</category>
      <category>안드로이드 코틀린</category>
      <category>코틀린</category>
      <category>코틀린 시작하기</category>
      <category>코틀린 프로젝트 생성</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/37</guid>
      <comments>https://sslee92.tistory.com/37#entry37comment</comments>
      <pubDate>Wed, 5 Mar 2025 17:34:45 +0900</pubDate>
    </item>
    <item>
      <title>[WPF / xaml] WPF UI 랜더링 완료 시점</title>
      <link>https://sslee92.tistory.com/34</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;개발을 하다보면 UI가 완전히 랜더링 된 시점을 정확히 잡아야 할 때가 있다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;처음 프로그램을 실행 시킨후 MainWindow가 로드될때 이벤트 순서는 아래와 같다&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;1. 생성자 호출&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;- 객체가 생성되는 단계로, 여기에서는 UI가 아직 로드되지 않은 상태다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;2.InitializeComponent()&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;- XAML에 정의된 UI 요소들이 로드되고, 초기화 된다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;3. Loaded 이벤트&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;- UI요소가 초기화되고 로드된 상태이지만, 아직 화면에는 그려지지 않은 상태다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;4. ContentRendered 이벤트&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;- 모든 UI 요소들이 실제로 화면에 렌더링이 완료된 직후 발생하는 이벤트다.&lt;br /&gt;&amp;nbsp; &amp;nbsp;즉, 사용자가 눈으로 확인 가능한 시점이다.&lt;br /&gt;&amp;nbsp;- 다만, ContentRendered 이벤트가 발생했다고 해서 &lt;br /&gt;&amp;nbsp; &amp;nbsp;이후 추가적인 UI 업데이트나 이벤트 처리가 없다는 것을 의미하지는 않는다.&lt;br /&gt;&amp;nbsp; &amp;nbsp;이후에도 UI의 변경사항으로 인해 추가적인 렌더링이 이루어질 수 있다.&lt;/blockquote&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt; ContentRendered &lt;/b&gt;&lt;/i&gt;이벤트는 실제로 UI 요소가 표시된 상태&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;즉, 화면이 사용자에게 보이는 순간 들어오는 이벤트이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 이벤트도 모든 UI 요소가 랜더링이 완료되었음을 보장하지만&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;ContentRendered&lt;span&gt; &lt;/span&gt;&lt;/b&gt;&lt;/i&gt;이벤트 이후 발생하는 상태도 있다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt; ApplicationIdle &lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: center;&quot;&gt;ApplicationIdle&lt;span&gt; 상태란?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;WPF에서는 정확히 &quot; &lt;span style=&quot;color: #333333; text-align: center;&quot;&gt;ApplicationIdle&quot;이라는 별도 이벤트가 존재하지는 않지만,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: center;&quot;&gt;일반적으로 응용 프로그램이 유휴상태에 들어갔다고 표현할 때가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;유휴상태&quot;의 정의는 다음과같다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666; background-color: #f6e199;&quot;&gt;&lt;i&gt;&lt;b&gt;모든 작업 큐가 비어있고, 현재 진행중인 모든 작업들이 완료된 상태&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;i&gt;모든 UI 렌더링이 완료된 상태&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;i&gt;바인딩 및 기타 모든 이벤트 처리가 완료된 상태&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;정리하자면, 아래 예제 코드의 실행 결과처럼 이벤트와 메서드 호출 순서를 이해할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;pre id=&quot;code_1733791563919&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; public MainWindow()
 {
     Console.WriteLine(&quot;1&quot;);

     InitializeComponent();

     Dispatcher.BeginInvoke(new Action(() =&amp;gt;
     {
         TestMethod();
     }), DispatcherPriority.ApplicationIdle);
 }

 private void Window_Loaded(object sender, RoutedEventArgs e)
 {
     Console.WriteLine(&quot;2&quot;);
 }

 private void Window_ContentRendered(object sender, EventArgs e)
 {
     Console.WriteLine(&quot;3&quot;);
 }

 private void TestMethod()
 {
     Console.WriteLine(&quot;4&quot;);
 }&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;i&gt; ContentRendered&lt;/i&gt; 와 &lt;i&gt;ApplicationIdle&lt;/i&gt; 차이점비교&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 120px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 11.5891%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 45.1938%; height: 20px;&quot;&gt;&lt;b&gt; ContentRendered &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 43.217%; height: 20px;&quot;&gt;&lt;b&gt; ApplicationIdle &lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 11.5891%; text-align: center; height: 40px;&quot;&gt;&lt;b&gt;발생시점&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 45.1938%; height: 40px;&quot;&gt;UI가 처음으로 사용자에게 랜더링 완료된 직후 발생&lt;/td&gt;
&lt;td style=&quot;width: 43.217%; height: 40px;&quot;&gt;모든 작업이 끝나고&lt;br /&gt;큐가 비어 유휴상태가 되었을때 발생&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 11.5891%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;발생빈도&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 45.1938%; height: 20px;&quot;&gt;한번만 발생 (초기 랜더링 후)&lt;/td&gt;
&lt;td style=&quot;width: 43.217%; height: 20px;&quot;&gt;유휴 상태가 될 때마다 여러번 발생 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 11.5891%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;사용목적&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 45.1938%; height: 20px;&quot;&gt;초기 화면 랜더링 직후의 초기화 작업&lt;/td&gt;
&lt;td style=&quot;width: 43.217%; height: 20px;&quot;&gt;랜더링 이후 유휴상태에서 부하가 적은 작업처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 11.5891%; text-align: center; height: 20px;&quot;&gt;&lt;b&gt;적합한 작업&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 45.1938%; height: 20px;&quot;&gt;UI 표시 직후 실행할 초기화 작업 (애니메이션 등)&lt;/td&gt;
&lt;td style=&quot;width: 43.217%; height: 20px;&quot;&gt;UI업데이트 후 부수작&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;</description>
      <category>c#/WPF</category>
      <category>.NET</category>
      <category>applicationidle</category>
      <category>C#</category>
      <category>contentrendered</category>
      <category>Dispatcher</category>
      <category>ui 이벤트 순서</category>
      <category>ui이벤트</category>
      <category>WPF</category>
      <category>wpf 화면 렌더링 완료 시점</category>
      <category>렌더링순서</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/34</guid>
      <comments>https://sslee92.tistory.com/34#entry34comment</comments>
      <pubDate>Tue, 10 Dec 2024 10:08:51 +0900</pubDate>
    </item>
    <item>
      <title>[WPF / xaml] FontFamily 리소스 동적 할당 메모리 누수</title>
      <link>https://sslee92.tistory.com/32</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;내가 가장 많이 사용하던 방식인&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;폰트를 리소스에 넣어서 리소스사전에 등록하고 사용하는 방식은&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;메모리를 많이먹게된다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://forum.dotnetdev.kr/t/wpf-fontfamily/9240&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://forum.dotnetdev.kr/t/wpf-fontfamily/9240&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1734943970854&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;WPF FontFamily 폰트 리소스 동적 할당시 메모리 누수&quot; data-og-description=&quot;프로그래밍을 하다보면, 디자인파일에 맞추기 위해 폰트를 설정합니다. 배포 특성상 타겟 윈도우에 폰트를 설치하기 꺼려지는 경우가 있는데요. 이때 어플리케이션과 함께 글꼴 패키징을 사용&quot; data-og-host=&quot;forum.dotnetdev.kr&quot; data-og-source-url=&quot;https://forum.dotnetdev.kr/t/wpf-fontfamily/9240&quot; data-og-url=&quot;https://forum.dotnetdev.kr/t/wpf-fontfamily/9240&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eC3VK/hyXSp7zGBf/y9kpmPOUOlaRm7cACB1LXk/img.png?width=1024&amp;amp;height=537&amp;amp;face=0_0_1024_537,https://scrap.kakaocdn.net/dn/G3ZTf/hyXStPGhpp/vDMVWWH9CeEC2cfbONrU2k/img.png?width=1024&amp;amp;height=537&amp;amp;face=0_0_1024_537,https://scrap.kakaocdn.net/dn/iAEey/hyXOeNqevq/MUaiDgJUyNBGOovv02gLGk/img.png?width=690&amp;amp;height=362&amp;amp;face=0_0_690_362&quot;&gt;&lt;a href=&quot;https://forum.dotnetdev.kr/t/wpf-fontfamily/9240&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://forum.dotnetdev.kr/t/wpf-fontfamily/9240&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eC3VK/hyXSp7zGBf/y9kpmPOUOlaRm7cACB1LXk/img.png?width=1024&amp;amp;height=537&amp;amp;face=0_0_1024_537,https://scrap.kakaocdn.net/dn/G3ZTf/hyXStPGhpp/vDMVWWH9CeEC2cfbONrU2k/img.png?width=1024&amp;amp;height=537&amp;amp;face=0_0_1024_537,https://scrap.kakaocdn.net/dn/iAEey/hyXOeNqevq/MUaiDgJUyNBGOovv02gLGk/img.png?width=690&amp;amp;height=362&amp;amp;face=0_0_690_362');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;WPF FontFamily 폰트 리소스 동적 할당시 메모리 누수&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;프로그래밍을 하다보면, 디자인파일에 맞추기 위해 폰트를 설정합니다. 배포 특성상 타겟 윈도우에 폰트를 설치하기 꺼려지는 경우가 있는데요. 이때 어플리케이션과 함께 글꼴 패키징을 사용&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;forum.dotnetdev.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;가능하다면 폰트를 설치하고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;설치된 폰트를 리소스사전에 등록후 사용하자&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/WPF</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/32</guid>
      <comments>https://sslee92.tistory.com/32#entry32comment</comments>
      <pubDate>Tue, 5 Nov 2024 18:04:23 +0900</pubDate>
    </item>
    <item>
      <title>[WPF] Tost Notification</title>
      <link>https://sslee92.tistory.com/30</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h1 style=&quot;background-color: #ffffff; color: #1f2328; text-align: center;&quot;&gt;&lt;i&gt;&lt;b&gt;ToastNotifications&lt;/b&gt;&lt;/i&gt;&lt;/h1&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/rafallopatka/ToastNotifications&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/rafallopatka/ToastNotifications&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1729658114894&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - rafallopatka/ToastNotifications: Toast notifications for WPF allows you to create and display rich notifications in WPF&quot; data-og-description=&quot;Toast notifications for WPF allows you to create and display rich notifications in WPF applications. It's highly configurable with set of built-in options like positions, behaviours, th...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/rafallopatka/ToastNotifications&quot; data-og-url=&quot;https://github.com/rafallopatka/ToastNotifications&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/LVr3p/hyXlScq3xz/mzHEQzrt3DoUOM7zdDtfnk/img.png?width=1200&amp;amp;height=600&amp;amp;face=958_112_1083_248,https://scrap.kakaocdn.net/dn/bjuca5/hyXlTPXdZ3/WNoOd8NNeXMV9pT3XxZ8yk/img.png?width=1200&amp;amp;height=600&amp;amp;face=958_112_1083_248&quot;&gt;&lt;a href=&quot;https://github.com/rafallopatka/ToastNotifications&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/rafallopatka/ToastNotifications&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/LVr3p/hyXlScq3xz/mzHEQzrt3DoUOM7zdDtfnk/img.png?width=1200&amp;amp;height=600&amp;amp;face=958_112_1083_248,https://scrap.kakaocdn.net/dn/bjuca5/hyXlTPXdZ3/WNoOd8NNeXMV9pT3XxZ8yk/img.png?width=1200&amp;amp;height=600&amp;amp;face=958_112_1083_248');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - rafallopatka/ToastNotifications: Toast notifications for WPF allows you to create and display rich notifications in WPF&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Toast notifications for WPF allows you to create and display rich notifications in WPF applications. It's highly configurable with set of built-in options like positions, behaviours, th...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 style=&quot;background-color: #ffffff; color: #1f2328; text-align: center;&quot;&gt;&lt;b&gt;&lt;i&gt;Notification.Wpf&lt;/i&gt;&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Platonenkov/Notification.Wpf&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/Platonenkov/Notification.Wpf&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1729658142326&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - Platonenkov/Notification.Wpf: Toast notifications for WPF (message, progress, image, any content)&quot; data-og-description=&quot;Toast notifications for WPF (message, progress, image, any content) - Platonenkov/Notification.Wpf&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/Platonenkov/Notification.Wpf&quot; data-og-url=&quot;https://github.com/Platonenkov/Notification.Wpf&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bJDglP/hyXlUagmb5/1qhwKVLZdqex6kfsgfp0vK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/1YEoB/hyXlVGZemT/pUnkktyKBW3cknHwmKI2K0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/Platonenkov/Notification.Wpf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/Platonenkov/Notification.Wpf&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bJDglP/hyXlUagmb5/1qhwKVLZdqex6kfsgfp0vK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/1YEoB/hyXlVGZemT/pUnkktyKBW3cknHwmKI2K0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - Platonenkov/Notification.Wpf: Toast notifications for WPF (message, progress, image, any content)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Toast notifications for WPF (message, progress, image, any content) - Platonenkov/Notification.Wpf&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/WPF</category>
      <category>.NET</category>
      <category>C#</category>
      <category>Notification</category>
      <category>tost</category>
      <category>WPF</category>
      <category>wpf tost notification</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/30</guid>
      <comments>https://sslee92.tistory.com/30#entry30comment</comments>
      <pubDate>Wed, 23 Oct 2024 13:35:58 +0900</pubDate>
    </item>
    <item>
      <title>[WPF / xaml] Rectangle - 점선으로 된 Border 그리기</title>
      <link>https://sslee92.tistory.com/29</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpXB3z/btsKeFrikdM/0C976OUD3KZHuxzVObR1b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpXB3z/btsKeFrikdM/0C976OUD3KZHuxzVObR1b0/img.png&quot; data-alt=&quot;결과물&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpXB3z/btsKeFrikdM/0C976OUD3KZHuxzVObR1b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpXB3z%2FbtsKeFrikdM%2F0C976OUD3KZHuxzVObR1b0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;514&quot; height=&quot;348&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과물&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;i&gt;Rectangle&lt;/i&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;Stroke&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&amp;nbsp;- Border에서 BorderBrush 역할&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;StrokeThickness&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&amp;nbsp;- Border에서 BorderThickness역할&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;RadiusX&lt;/span&gt;&amp;nbsp;,&amp;nbsp;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;RadiusY&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&amp;nbsp;- Border에서 CornerRadius역할을 하지만&amp;nbsp;CornerRadius 와는 사용법이 좀다르다(사용해보면 느낌이 바로온다)&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;Fill&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&amp;nbsp;- Border에서 BackGround역할&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;DoubleCollection&amp;nbsp;&lt;/span&gt;첫번째 항목 (예제코드에서 5)&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&amp;nbsp;- 점선의 길이 값&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;DoubleCollection&amp;nbsp;&lt;/span&gt;두번째 항목 (예제코드에서 1)&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&amp;nbsp;- 점선 사이의 거리 값&lt;br /&gt;
&lt;pre id=&quot;code_1729587669573&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Rectangle Stroke=&quot;Red&quot;
           StrokeThickness=&quot;2&quot;
           RadiusX=&quot;15&quot;
           RadiusY=&quot;15&quot;
           Width=&quot;200&quot;
           Height=&quot;100&quot;
           Fill=&quot;LightBlue&quot;&amp;gt;
    &amp;lt;Rectangle.StrokeDashArray&amp;gt;
        &amp;lt;DoubleCollection&amp;gt;5, 1&amp;lt;/DoubleCollection&amp;gt;
    &amp;lt;/Rectangle.StrokeDashArray&amp;gt;
&amp;lt;/Rectangle&amp;gt;​&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/WPF</category>
      <category>border</category>
      <category>WPF</category>
      <category>wpf 점선</category>
      <category>wpf 점선 border</category>
      <category>xaml</category>
      <category>점선 border</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/29</guid>
      <comments>https://sslee92.tistory.com/29#entry29comment</comments>
      <pubDate>Tue, 22 Oct 2024 18:01:39 +0900</pubDate>
    </item>
    <item>
      <title>[git] .gitignore를 수정했는데 적용되지 않을 때 해결 방법</title>
      <link>https://sslee92.tistory.com/28</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;개발을 하다가 실수로 이미 Git에 올라간 파일이나 폴더를 뒤늦게 .gitignore에 추가하면,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이미 추적 중인 파일은 무시되지 않는다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이럴 땐 아래 명령어를 Git Bash에서 한줄씩 실행하면 된다.&lt;/p&gt;
&lt;pre class=&quot;csharp&quot; style=&quot;background-color: #f6f8fa; color: #24292e; text-align: start;&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;git rm -r --cached .  # 이미 추적 중인 파일의 인덱스를 초기화 (.gitignore 적용을 위해)
git add .             # .gitignore에 따라 파일을 다시 추가
git commit -m &quot;fixed untracked files&quot;  # 변경사항 커밋&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git</category>
      <category>Git</category>
      <category>git bash</category>
      <category>github</category>
      <category>gitignore</category>
      <category>개발 팁</category>
      <category>버전 관리</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/28</guid>
      <comments>https://sslee92.tistory.com/28#entry28comment</comments>
      <pubDate>Wed, 21 Aug 2024 16:17:31 +0900</pubDate>
    </item>
    <item>
      <title>[WPF] Binding 속성들</title>
      <link>https://sslee92.tistory.com/27</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Binding&lt;/b&gt;에서 제공해주는 여러 속성들을 정리해보려고한다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;WPF&lt;/b&gt;에서 &lt;b&gt;Binding&lt;/b&gt;속성은 &lt;b&gt;XAML&lt;/b&gt;에서 &lt;b&gt;UI&lt;/b&gt; 요소를 데이터 소스의 속성과 연결하는 데 사용된다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Binding&lt;/b&gt;은 여러 속성을 제공하여 다양한 방법으로 데이터를 연결 할 수 있게 도와준다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;어떤 속성들이 있고, 해당 속성이 어떤 역할을 하는지 알아보자&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;i&gt;&lt;b&gt;목차&lt;/b&gt;&lt;/i&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Path&lt;br /&gt;Source&lt;br /&gt;ElementName&lt;br /&gt;RelativeSource&lt;br /&gt;Mode&lt;br /&gt;UpdateSourceTrigger&lt;br /&gt;Converter&lt;br /&gt;ConverterParameter&lt;br /&gt;StringFormat&lt;br /&gt;FallbackValue&lt;br /&gt;TargetNullValue&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Path&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;바인딩할 데이터 소스의 속성 경로를 지정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;pre id=&quot;code_1721795263568&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!--WPF는 내부적으로 이를 Path 속성에 대한 값으로 해석--&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Title}&quot; /&amp;gt;

&amp;lt;!--Binding 객체의 Path 속성을 명시적으로 지정--&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Path=Title}&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;i&gt;Source&lt;/i&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;바인딩할 데이터 소스를 지정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;1&lt;br /&gt;공통으로 관리하는 테마Color, 폰트 등을 활용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1721796484257&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- App.xaml 리소스에 추가--&amp;gt;
&amp;lt;SolidColorBrush x:Key=&quot;TitleColor&quot; Color=&quot;Blue&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1721796406593&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;TextBlock Text=&quot;{Binding Title}&quot; Foreground=&quot;{Binding Source={StaticResource TitleColor}}&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;2&lt;br /&gt;Person&amp;nbsp;객체의&amp;nbsp;Name&amp;nbsp;속성과&amp;nbsp;바인딩&lt;br /&gt;이렇게 써본적은 없지만 가능은하다&lt;/p&gt;
&lt;pre id=&quot;code_1721796419859&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Person
{
    public string Name { get; set; }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1721795640340&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Window.Resources&amp;gt;
	&amp;lt;local:Person x:Key=&quot;person&quot; Name=&quot;Seung Soo Lee&quot; /&amp;gt;
&amp;lt;/Window.Resources&amp;gt;
    
&amp;lt;TextBlock Text=&quot;{Binding Source={StaticResource person}, Path=Name}&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;ElementName&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;바인딩할 데이터 소스로 사용할 다른 요소의 이름을 지정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;TextBox의 Text 속성을 TextBlock의 Text 속성에 바인딩&lt;br /&gt;TextBox에 텍스트를 입력하면 TextBlock이 해당 텍스트를 실시간으로 표시하는 예제&lt;/p&gt;
&lt;pre id=&quot;code_1721796852707&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    &amp;lt;Grid&amp;gt;
        &amp;lt;StackPanel&amp;gt;
            &amp;lt;TextBox x:Name=&quot;InputTextBox&quot; Width=&quot;200&quot; Margin=&quot;10&quot; /&amp;gt;
            &amp;lt;TextBlock Text=&quot;{Binding ElementName=InputTextBox, Path=Text}&quot; FontSize=&quot;16&quot; Margin=&quot;10&quot; /&amp;gt;
        &amp;lt;/StackPanel&amp;gt;
    &amp;lt;/Grid&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;RelativeSource&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;바인딩할 데이터 소스로 사용할 상대 경로를 지정 &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Button 상위 요소중에서 Window 타입의 요소를 찾아&lt;br /&gt;Window타입 요소의 Title을 바인딩하는 예제&lt;/p&gt;
&lt;pre id=&quot;code_1721799963045&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Window x:Class=&quot;WpfApp.MainWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        Title=&quot;RelativeSource 예제&quot; Height=&quot;200&quot; Width=&quot;300&quot;&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;StackPanel HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot;&amp;gt;
            &amp;lt;Button Content=&quot;{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}&quot; Width=&quot;200&quot; Height=&quot;50&quot; /&amp;gt;
        &amp;lt;/StackPanel&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Mode&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;바인딩 모드를 지정&lt;br /&gt;(OneWay,&amp;nbsp;TwoWay,&amp;nbsp;OneWayToSource,&amp;nbsp;OneTime) &lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;OneWay&lt;/b&gt;&lt;/i&gt; &lt;br /&gt;소스의 값이 변경되면 대상에 반영되지만, 대상의 값이 변경되어도 소스에는 반영되지 않는다&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;TwoWay&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;모드는 소스와 대상 모두의 값이 변경되면 서로에게 반영된다&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;OneWayToSource&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;대상의 값이 변경되면 소스에 반영되지만, 소스의 값이 변경되어도 대상에는 반영되지 않는다&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;OneTime&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;바인딩이 처음 설정될 때 한 번만 값을 가져오고 이후에는 업데이트되지 않는다&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Default&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: center;&quot;&gt;default값은 속성마다 다르다&lt;br /&gt;&lt;/span&gt;TextBox의 경우 default는 TwoWay이고, TexBlock의 경우에는 OneWay이다&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1721801218728&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;TextBlock Text=&quot;{Binding Name, Mode=OneWay}&quot;/&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Name, Mode=TwoWay}&quot;/&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Name, Mode=OneWayToSource}&quot;/&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Name, Mode=OneTime}&quot;/&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Name, Mode=Default}&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Mode&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;데이터소스가 업데이트되는 시점을 지정&lt;br /&gt;주요 값으로는 &lt;br /&gt;PropertyChanged, LostFocus, Explicit등 이 있다&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;PropertyChanged&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;바인딩된 속성이 변경될 때마다 데이터 소스를 업데이트한다&lt;br /&gt;아래 예제에서는 TextBox에 문자열을 입력하면 TextBlock에 바로 나타난다&lt;/p&gt;
&lt;pre id=&quot;code_1721802707348&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;TextBox Text=&quot;{Binding Name, UpdateSourceTrigger=PropertyChanged}&quot;/&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Name}&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;LostFocus&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;바인딩된 요소가 포커스를 잃을 때 데이터 소스를 업데이트한다&lt;br /&gt;아래 예제에서는 TextBox에 문자열을 입력한 후&lt;br /&gt;TextBox가 포커스를 잃는 순간에 TextBlock에 나타난다&lt;/p&gt;
&lt;pre id=&quot;code_1721802762621&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;TextBox Text=&quot;{Binding Name, UpdateSourceTrigger=LostFocus}&quot;/&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Name}&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Explicit&lt;/i&gt;&lt;/b&gt; &lt;br /&gt;바인딩된 요소에서 명시적으로 소스 업데이트를 트리거할 때 데이터 소스를 업데이트한다&lt;br /&gt;UpdateSource() 메서드를 호출해야한다.&lt;/p&gt;
&lt;pre id=&quot;code_1721802998095&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;TextBox x:Name=&quot;InputTextBox&quot; Text=&quot;{Binding Name, UpdateSourceTrigger=Explicit}&quot;/&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Name}&quot;/&amp;gt;
&amp;lt;Button Click=&quot;Button_Click&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1721803014610&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void Button_Click(object sender, RoutedEventArgs e)
{
    var binding = InputTextBox.GetBindingExpression(System.Windows.Controls.TextBox.TextProperty);
    binding.UpdateSource();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Converter&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;바인딩 데이터를 변환하는 데 사용할 변환기를 지정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Converter를 사용하면 바인딩된 데이터의 형식을 변환할 수 있다&lt;br /&gt;아래 예제에서는 TextBox에 값을 입력하면&lt;br /&gt;대문자로 Convert되어 TextBlock에 보여진다&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/i&gt; IValueConverter 인터페이스를 상속받는 Class가 필요함&lt;/p&gt;
&lt;pre id=&quot;code_1721804541982&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class UpperCaseConverter : IValueConverter
{
    // Convert 메서드는 소스 값을 대상 값으로 변환한다
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 값이 문자열인지 확인한다
        if (value is string stringValue)
        {
            // 문자열을 대문자로 변환하여 반환한다
            return stringValue.ToUpper();
        }
        // 값이 문자열이 아니면 그대로 반환한다
        return value;
    }

    // ConvertBack 메서드는 대상 값을 소스 값으로 변환한다
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 값이 문자열인지 확인한다
        if (value is string stringValue)
        {
            // 문자열을 소문자로 변환하여 반환한다
            return stringValue.ToLower();
        }
        // 값이 문자열이 아니면 그대로 반환한다
        return value;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;Converter를 리소스로 정의하고 Key값을 이용해 바인딩에 사용&lt;/p&gt;
&lt;pre id=&quot;code_1721804660280&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Window.Resources&amp;gt;
    &amp;lt;local:UpperCaseConverter x:Key=&quot;upperCaseConverter&quot; /&amp;gt;
&amp;lt;/Window.Resources&amp;gt;
&amp;lt;Grid&amp;gt;
    &amp;lt;StackPanel HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot;&amp;gt;
        &amp;lt;TextBox Text=&quot;{Binding Name, UpdateSourceTrigger=PropertyChanged}&quot; /&amp;gt;
        &amp;lt;TextBlock Text=&quot;{Binding Name, Converter={StaticResource upperCaseConverter}}&quot; /&amp;gt;
    &amp;lt;/StackPanel&amp;gt;
&amp;lt;/Grid&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;ConverterParameter&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;변환기에 전달할 매개변수를 지정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;ConverterParameter를 사용하여 &lt;br /&gt;위에서작성한 Convert에 추가로 매개변수를 전달해 줄 수 있다&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: center;&quot;&gt;IValueConverter 인터페이스를 상속받는 Class가 필요함&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1721805434636&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class CaseConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string stringValue)
        {
            // 파라미터 값이 문자열인지 확인한다
            if (parameter is string param)
            {
                // 파라미터 값에따라 처리한다
                if(param == &quot;upper&quot;)
                {
                    return stringValue.ToUpper();
                }
                else if(param == &quot;lower&quot;)
                {
                    return stringValue.ToLower();
                }
            }
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Convert와 동일하게작성
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;2&lt;br /&gt;&lt;/b&gt;&lt;/i&gt; &lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: center;&quot;&gt;Converter를 리소스로 정의하고 Key값을 이용해 바인딩에 사용&lt;/span&gt; &lt;br /&gt;ConverterParameter로 매개변수 전달&lt;/p&gt;
&lt;pre id=&quot;code_1721805494405&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Window.Resources&amp;gt;
    &amp;lt;local:CaseConverter x:Key=&quot;caseConverter&quot; /&amp;gt;
&amp;lt;/Window.Resources&amp;gt;
&amp;lt;Grid&amp;gt;
    &amp;lt;StackPanel HorizontalAlignment=&quot;Center&quot;
                VerticalAlignment=&quot;Center&quot;&amp;gt;
        &amp;lt;TextBox Text=&quot;{Binding Name, UpdateSourceTrigger=PropertyChanged}&quot;
                 /&amp;gt;
        &amp;lt;!-- 대문자로 변환 --&amp;gt;
        &amp;lt;TextBlock Text=&quot;{Binding Name, Converter={StaticResource caseConverter}, ConverterParameter=upper}&quot;/&amp;gt;
        &amp;lt;!-- 소문자로 변환 --&amp;gt;
        &amp;lt;TextBlock Text=&quot;{Binding Name, Converter={StaticResource caseConverter}, ConverterParameter=lower}&quot; /&amp;gt;
    &amp;lt;/StackPanel&amp;gt;
&amp;lt;/Grid&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;i&gt;StringFormat&lt;/i&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;바인딩 데이터를 문자열로 포맷하는 방법을 지정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;DateTime을 문자열로 포맷하는 예제&lt;/p&gt;
&lt;pre id=&quot;code_1721806892743&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!-- DateTime형식 ex&amp;gt; 1992-01-22 --&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding TestDate, StringFormat='{}{0:yyyy-MM-dd}'}&quot; /&amp;gt;

&amp;lt;!-- DateTime형식 ex&amp;gt; January 22, 1992 --&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding TestDate, StringFormat='{}{0:MMMM dd, yyyy}'}&quot; /&amp;gt;

&amp;lt;!-- 소수점 아래 두 자리까지 표시, 마지막 반올림 ex&amp;gt; 값이 1.159이면 1.16으로 표기--&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Amount, StringFormat='{}{0:F2}'}&quot; /&amp;gt;

&amp;lt;!-- 천 단위 구분 기호 사용 ex&amp;gt; 12,000 --&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Amount, StringFormat='{}{0:N0}'}&quot; /&amp;gt;

&amp;lt;!-- 백분율 ex&amp;gt; 1 : 100% , 0.25 : 25% 소수점은 P1, P2--&amp;gt;
&amp;lt;TextBlock Text=&quot;{Binding Amount, StringFormat='{}{0:P0}'}&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;FallbackValue&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;바인딩할 수 없을때 사용할 값을 지정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;FallbackValue는 바인딩이 실패 했을때 &lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: center;&quot;&gt;사용할 값을 지정하는 속성이다&lt;/span&gt; &lt;br /&gt;아래 예제에서&lt;br /&gt;Name이라는 변수가 없다고 가정하면 TextBlock에는 기본값인 &quot;이승수&quot;가 노출된&lt;/p&gt;
&lt;pre id=&quot;code_1721807907077&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;TextBlock Text=&quot;{Binding Name, FallbackValue='이승수'}&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt; TargetNullValue &lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;소스 값이 null일 때 사용할 값을 지정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;TargetNullValue는 바인딩된 값이 null일 때 표시할 값을 지정하는 속성이다&lt;br /&gt;아래 예제에서는&lt;br /&gt;Button을 클릭했을때 Name을 null로 지정해주었다&lt;br /&gt;그러면 Button을 클릭했을때 TextBlock에는 기본값인 &quot;이승수&quot;가 노출된다&lt;/p&gt;
&lt;pre id=&quot;code_1721808930601&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;TextBlock Text=&quot;{Binding Name, TargetNullValue='이승수'}&quot;/&amp;gt;
&amp;lt;Button Command=&quot;{Binding TestCommand}&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/WPF</category>
      <category>WPF</category>
      <category>wpf binding</category>
      <category>wpf 바인딩</category>
      <category>wpf 바인딩 속성</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/27</guid>
      <comments>https://sslee92.tistory.com/27#entry27comment</comments>
      <pubDate>Fri, 26 Jul 2024 09:15:45 +0900</pubDate>
    </item>
    <item>
      <title>[WPF] CommunityToolkit.Mvvm</title>
      <link>https://sslee92.tistory.com/26</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Text Binding 예제&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;CommunityToolkit을 사용하지 않은 예제&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1721789046255&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MainWindowViewModel : INotifyPropertyChanged
{
	private string _title = string.Empty;

	public string Title
	{
	    get { return _title; }
	    set { _title = value; OnPropertyChanged(nameof(Title)); }
	}

	public MainWindowViewModel()
	{
	    Title = &quot;Test&quot;;
	}

	public event PropertyChangedEventHandler PropertyChanged;

	protected virtual void OnPropertyChanged(string propertyName)
	{
	    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1721789164974&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;TextBlock Text=&quot;{Binding Title}&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;CommunityToolkit을 사용한 예제&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1721789072327&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public partial class MainWindowViewModel : ObservableObject
{
    [ObservableProperty]
    private string title;

    public MainWindowViewModel()
    {
        Title = &quot;Test&quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1721789186118&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;TextBlock Text=&quot;{Binding Title}&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Command 예제&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;CommunityToolkit을 사용하지 않은 예제&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; ICommand&lt;/b&gt; 인터페이스를 구현한 &lt;b&gt;Class&lt;/b&gt;를 사용하여 명령을 처리한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기능을 구현할 &lt;b&gt;ViewModel&lt;/b&gt;에서 명령을 정의한 &lt;b&gt;View&lt;/b&gt;에서 이를 &lt;b&gt;Binding&lt;/b&gt;한다.&lt;/p&gt;
&lt;pre id=&quot;code_1721789675115&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; public class DelegateCommand : ICommand
 {
     private readonly Func&amp;lt;bool&amp;gt; canExecute;
     private readonly Action execute;

     public DelegateCommand(Action execute) : this(execute, null)
     {
     }

     public DelegateCommand(Action execute, Func&amp;lt;bool&amp;gt; canExecute)
     {
         this.execute = execute;
         this.canExecute = canExecute;
     }

     public event EventHandler CanExecuteChanged;

     public bool CanExecute(object o)
     {
         if (this.canExecute == null)
         {
             return true;
         }
         return this.canExecute();
     }

     public void Execute(object o)
     {
         this.execute();
     }

     public void RaiseCanExecuteChanged()
     {
         if (this.CanExecuteChanged != null)
         {
             this.CanExecuteChanged(this, EventArgs.Empty);
         }
     }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1721793479560&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private ICommand _saveCommand;
public ICommand SaveCommand
{
    get { return (this._saveCommand) ?? (this._saveCommand = new DelegateCommand(Save)); }
}

//또는
public System.Windows.Input.ICommand SaveCommand =&amp;gt; new DelegateCommand(Save);

private void Save()
{
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1721793939304&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Button Command=&quot;{Binding SaveCommand}&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;CommunityToolkit을 사용한 예제&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1721793896928&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public partial class MainWindowViewModel : ObservableObject
{
    [RelayCommand]
    private void Save()
    {

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1721793953031&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Button Command=&quot;{Binding SaveCommand}&quot;/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/26</guid>
      <comments>https://sslee92.tistory.com/26#entry26comment</comments>
      <pubDate>Wed, 24 Jul 2024 11:42:48 +0900</pubDate>
    </item>
    <item>
      <title>[WPF / WindowsFormsHost]  WPF에서 Winform 컨트롤 사용하기</title>
      <link>https://sslee92.tistory.com/25</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;참조추가&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;어셈블리에서 &lt;b&gt;WindowsFormsIntegration&lt;/b&gt;을 추가&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;537&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjxQ0s/btsGCzuz0ae/YOMK23tHLOna8UWPv9O1fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjxQ0s/btsGCzuz0ae/YOMK23tHLOna8UWPv9O1fk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjxQ0s/btsGCzuz0ae/YOMK23tHLOna8UWPv9O1fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjxQ0s%2FbtsGCzuz0ae%2FYOMK23tHLOna8UWPv9O1fk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;783&quot; height=&quot;537&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;537&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/WPF</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/25</guid>
      <comments>https://sslee92.tistory.com/25#entry25comment</comments>
      <pubDate>Tue, 16 Apr 2024 11:51:07 +0900</pubDate>
    </item>
    <item>
      <title>[세미나] Blazor / WPF / MAUI 밋업</title>
      <link>https://sslee92.tistory.com/18</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2024년 3월 28일 목요일&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;마이크로소프트 코리아&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;본사에서&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인프라지스틱스&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;마이크로소프트&lt;/b&gt;의 후원으로 진행되는 무료 세미나에 참석하게 되었다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;평소 &lt;b&gt;닷넷데브&lt;/b&gt; 커뮤니티에서 관심있게 봐왔던 &lt;br /&gt;이재웅 개발자님께서 직접 연락을 주셨다!&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이재웅 개발자님께서는 &lt;b&gt;WPF&lt;/b&gt; 세션을 맡아서 진행하셨고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;WPF&lt;/b&gt;뿐만 아니라&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Blazor&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;MAUI&lt;/b&gt;세션도 함께 진행하였다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;밋업.png&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;1341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0JlWi/btsGfww8rde/bNB2Qq3ENleXsbyrtfM7xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0JlWi/btsGfww8rde/bNB2Qq3ENleXsbyrtfM7xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0JlWi/btsGfww8rde/bNB2Qq3ENleXsbyrtfM7xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0JlWi%2FbtsGfww8rde%2FbNB2Qq3ENleXsbyrtfM7xk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1001&quot; height=&quot;1341&quot; data-filename=&quot;밋업.png&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;1341&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #1f2328; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;WPF 프로젝트 매니징에 필요한 좋은 습관 TOP 10&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;WPF 세션의 주제는 &lt;b&gt;WPF 프로젝트 매니징에 필요한 좋은습관 TOP 10&lt;/b&gt; 이였다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Blazor&lt;/b&gt;와 &lt;b&gt;MAUI&lt;/b&gt;는 평소 관심은 있었으나 접할 기회가 없었고,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이번 세미나를 통해서 느낀점은&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아직 기술적인 지원이 미비한거같고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;추후에 필요할때 공부해도 늦지 않겠다고 판단하여&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;블로그에는 &lt;b&gt;WPF&lt;/b&gt; 세션만 다루게 되었다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이재웅 개발자님의 git에도 정리가 되어있는 내용이지만&lt;br /&gt;한번더 정리하고 작성하며 밋업의 내용들을 익히고자 블로그를 작성하게 되었다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;목차&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;WPF 구성 요소&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Application&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Current&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;MainWindow&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;GetWindow&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Current/MainWindow 관리 설계&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;닷넷 버전 선택&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;닷넷 Standard 버전의 차이점 (2.0.2.1)&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;닷넷 코어 기반의 멀티 타겟팅 (라이브러리)&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;런타임에서의 라이브러리&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;조건부 컴파일 (Conditional Compilation)&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;타이트한 접근 제한자&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;InotifyPropertyChanged 인터페이스 구현&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;nameof 활용&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;람다식 속성 활용&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;어트리뷰트 활용 (CommunityToolkit.Mvvm)&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;OnPropertyChanged 방식의 채택&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #1f2328; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;WPF 구성 요소&lt;/b&gt;&lt;/i&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;background-color: #e6f5ff; color: #0070d1; text-align: start;&quot; href=&quot;https://sslee92.tistory.com/19&quot;&gt;2024.04.03 - [c#/세미나] - [세미나] Blazor / WPF / MAUI 밋업 (WPF 구성 요소)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712138383172&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[세미나] Blazor / WPF / MAUI 밋업 (WPF 구성 요소)&quot; data-og-description=&quot;&quot; data-og-host=&quot;sslee92.tistory.com&quot; data-og-source-url=&quot;https://sslee92.tistory.com/19&quot; data-og-url=&quot;https://sslee92.tistory.com/19&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/19&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sslee92.tistory.com/19&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[세미나] Blazor / WPF / MAUI 밋업 (WPF 구성 요소)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sslee92.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Application / &lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;b&gt;Current / &lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;b&gt;MainWindow / &lt;/b&gt;&lt;/i&gt;&lt;b&gt;&lt;i&gt;GetWindow&lt;/i&gt;&lt;/b&gt;&lt;i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;background-color: #e6f5ff; color: #0070d1; text-align: start;&quot; href=&quot;https://sslee92.tistory.com/20&quot;&gt;2024.04.03 - [c#/세미나] - [세미나] Blazor / WPF / MAUI 밋업 (Application, Current, MainWindow, GetWindow)&lt;/a&gt; &lt;i&gt;&lt;b&gt;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712138387755&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[세미나] Blazor / WPF / MAUI 밋업 (Application, Current, MainWindow, GetWindow)&quot; data-og-description=&quot;&quot; data-og-host=&quot;sslee92.tistory.com&quot; data-og-source-url=&quot;https://sslee92.tistory.com/20&quot; data-og-url=&quot;https://sslee92.tistory.com/20&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/20&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sslee92.tistory.com/20&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[세미나] Blazor / WPF / MAUI 밋업 (Application, Current, MainWindow, GetWindow)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sslee92.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;닷넷 버전선택 및&lt;/b&gt;&lt;/i&gt;&lt;b&gt;&lt;i&gt;&lt;/i&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;닷넷 Standard 버전의 차이점 (2.0 / 2.1)&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;background-color: #e6f5ff; color: #0070d1; text-align: start;&quot; href=&quot;https://sslee92.tistory.com/21&quot;&gt;2024.04.03 - [c#/세미나] - [세미나] Blazor / WPF / MAUI 밋업 (닷넷 버전선택)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712138664428&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[세미나] Blazor / WPF / MAUI 밋업 (닷넷 버전선택)&quot; data-og-description=&quot;&quot; data-og-host=&quot;sslee92.tistory.com&quot; data-og-source-url=&quot;https://sslee92.tistory.com/21&quot; data-og-url=&quot;https://sslee92.tistory.com/21&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/21&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sslee92.tistory.com/21&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[세미나] Blazor / WPF / MAUI 밋업 (닷넷 버전선택)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sslee92.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;멀티 타겟팅 라이브러리&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;background-color: #e6f5ff; color: #0070d1; text-align: start;&quot; href=&quot;https://sslee92.tistory.com/22&quot;&gt;2024.04.03 - [c#/세미나] - [세미나] Blazor / WPF / MAUI 밋업 (멀티 타겟팅 라이브러리)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1712216334353&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[세미나] Blazor / WPF / MAUI 밋업 (멀티 타겟팅 라이브러리)&quot; data-og-description=&quot;&quot; data-og-host=&quot;sslee92.tistory.com&quot; data-og-source-url=&quot;https://sslee92.tistory.com/22&quot; data-og-url=&quot;https://sslee92.tistory.com/22&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/22&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://sslee92.tistory.com/22&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[세미나] Blazor / WPF / MAUI 밋업 (멀티 타겟팅 라이브러리)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;sslee92.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/세미나</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/18</guid>
      <comments>https://sslee92.tistory.com/18#entry18comment</comments>
      <pubDate>Thu, 11 Apr 2024 12:50:38 +0900</pubDate>
    </item>
    <item>
      <title>[세미나] Blazor / WPF / MAUI 밋업 (INotifyPropertyChanged 구현)</title>
      <link>https://sslee92.tistory.com/24</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt; [ObservableProperty] 어트리뷰트 활용 &lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;보통은 아래 코드처럼&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CommunityToolkit.Mvvm&lt;/b&gt;을 통해 속성 자체를 생략하여 편리하게 사용하지만&lt;/p&gt;
&lt;pre id=&quot;code_1712280727903&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[ObservableProperty]
private _title { get; set; }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;INotifyPropertyChanged&amp;nbsp;&lt;/b&gt;를 직접 구현해보고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이해하는것은 &lt;b&gt;MVVM&lt;/b&gt;을 이해하는대에 큰 도움이 된다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위 코드가 나오기까지 어떠한 과정들이 생략 되었는지 알아보자&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #1f2328; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;INotifyPropertyChanged 구현&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;&lt;b&gt;MVVM&lt;/b&gt; 패턴의 실체와도 같은 &lt;b&gt;INotifyPropertyChanged&lt;/b&gt;를 통해 바인딩 가능한 속성을 만들게 된다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #1f2328;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;또한 &lt;b&gt;WindowsBase.dll&lt;/b&gt;에 포함된 이 상징적인 인터페이스를 한번 들여다 볼 필요가 있다&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #1f2328;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;생각보다 많은 WPF 개발자들이 이를 직접 구현하여 사용하기도 한다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #1f2328;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;나또한 &lt;b&gt;MVVM&lt;/b&gt;을 처음 접했을때 라이브러리를 사용하지않고,&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #1f2328;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;직접 구현하여 사용하였는데&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #1f2328;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;이번 세미나에서 &lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;&lt;b&gt;INotifyPropertyChanged&lt;/b&gt; 구현에 관련된 내용이 나와 반가웠다&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1712280031974&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MainWindowViewmodel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;이 인터페이스는 &lt;b&gt;OnPropertyChanged&lt;/b&gt; 메서드를 인터페이스 멤버로 구현하도록 한다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 &lt;b&gt;Setter&lt;/b&gt;를 통해 속성의 변화를 뷰에서 감지하도록 알리는 로직을 구현할 수 있게 된다&lt;/p&gt;
&lt;pre id=&quot;code_1712280098855&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private string _title;

public string Title 
{
    get 
    {
        return _title;
    }
    set 
    {
        _title = value; OnPropertyChanged(&quot;Title&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이방식은 아주 클래식한 문법이다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Title&lt;/b&gt; 속성의 이름을 문자열로 직접 입력하여 보내게 된다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 이 방식은 속성의 이름이 변경되었을 때도 싱크를 함께 맞추어야 하며&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;오타를 범할 수 도 있게 된다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;nameof 활용&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;더 좋은방법은 &lt;b&gt;nameof&lt;/b&gt;를 활용하는것이다&lt;/p&gt;
&lt;pre id=&quot;code_1712280207476&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;set 
{
    _title = value; OnPropertyChanged(nameof(Title));
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 되면 속성 이름의 오타를 범하는 실수를 방지하고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;속성 이름 변경에 따른 추가 작업을 줄일 수 있다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1712543077569&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    internal class MainWindowViewmodel : INotifyPropertyChanged
    {
        private string _title = string.Empty;

        public string Title
        {
            get { return _title; }
            set { _title = value; OnPropertyChanged(nameof(Title)); }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/세미나</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/24</guid>
      <comments>https://sslee92.tistory.com/24#entry24comment</comments>
      <pubDate>Fri, 5 Apr 2024 10:45:51 +0900</pubDate>
    </item>
    <item>
      <title>[세미나] Blazor / WPF / MAUI 밋업 (멀티 타겟팅 라이브러리)</title>
      <link>https://sslee92.tistory.com/22</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;멀티 타겟팅 라이브러리&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;.NET&lt;/b&gt;을 기반으로 한 멀티 타겟팅 라이브러리를 구현&lt;/span&gt;하는 방법이다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;.NET &lt;/b&gt;기반의 라이브러리 클래스를 생성하게되면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래와 같이 프로젝트 코드가 구성되어 생성된다&lt;/p&gt;
&lt;pre class=&quot;csharp&quot; style=&quot;background-color: #f6f8fa; color: #1f2328; text-align: start;&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;&amp;lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&amp;gt;

  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;TargetFramework&amp;gt;net8.0&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;ImplicitUsings&amp;gt;enable&amp;lt;/ImplicitUsings&amp;gt;
    &amp;lt;Nullable&amp;gt;enable&amp;lt;/Nullable&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

&amp;lt;/Project&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 &lt;b&gt;TargetFramework&lt;/b&gt;를 &lt;b&gt;TargetFrameworks&lt;/b&gt; 로&lt;b&gt; s&lt;/b&gt;만 붙여주고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래와같이 멀티 타겟을 설정할 수 있다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;추가로&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: center;&quot;&gt;&lt;b&gt;ImplicitUsings&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Nullable&lt;/b&gt; 두가지 특성을&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;enable&lt;/b&gt;에서 &lt;b&gt;disable&lt;/b&gt;로 변경 해주어야 한다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;csharp&quot; style=&quot;background-color: #f6f8fa; color: #1f2328; text-align: start;&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;&amp;lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&amp;gt;

  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;TargetFrameworks&amp;gt;net48;net8.0&amp;lt;/TargetFrameworks&amp;gt;
    &amp;lt;ImplicitUsings&amp;gt;disable&amp;lt;/ImplicitUsings&amp;gt;
    &amp;lt;Nullable&amp;gt;disable&amp;lt;/Nullable&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

&amp;lt;/Project&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt; &lt;i&gt;&lt;b&gt;.NET Framework 4.8 추가&lt;/b&gt;&lt;/i&gt; &lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;런타임에서의 라이브러리&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;&lt;b&gt;TargetFrameworks&lt;/b&gt;를 통해 설정된 버전은&lt;br /&gt;각각 디렉토리에 따로 빌드된것을 확인 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;.NET&lt;/b&gt; 또는 &lt;b&gt;.NET Framework&lt;/b&gt;에서 해당 라이브러리를 참조한다면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;참조를 한 프로젝트의 버전에 따라 자동으로 &lt;b&gt;DLL&lt;/b&gt;이 매칭&lt;/span&gt;된다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 별 다른 설정없이 멀티 타겟팅 형식의 라이브러리만 잘 참조하고 사용하기만 하면 된다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;멀티 타겟팅 구현 규칙&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;멀티 타겟팅 라이브러리를 구현할 때 지켜야 할 단 하나의 규칙이 있다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;멋티 타겟으로 포함된 닷넷중 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;가장&lt;span style=&quot;background-color: #f6e199;&quot;&gt; 낮은 버전&lt;/span&gt;&lt;/b&gt;&lt;b&gt;을 기준으로 구현&lt;/b&gt;&lt;/span&gt;해야 한다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;위에서 작성한것 처럼&lt;br /&gt;&lt;b&gt;.NET Framework 4.8&lt;/b&gt;과 &lt;b&gt;.NET8&lt;/b&gt;을 타겟으로 했다면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;둘중 낮은 버전인&lt;b&gt; .NET Framework 4.8&lt;/b&gt; 에서 동작이 가능한 문법만 사용이 가능하다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;예를들어 &lt;b&gt;new();&lt;/b&gt;와 같은 생성자 축약은 사용할 수 없게 된다&lt;/p&gt;
&lt;pre id=&quot;code_1712209091370&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// .NET Framework 4.8에서 사용 불가
TestClass testClass = new();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 &lt;b&gt;CommunityToolkit&lt;/b&gt;과 같은 라이브러리 또한&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;.NET 6.0&lt;/b&gt; 이상에서만&lt;b&gt; [ObservableProperty] &lt;/b&gt;와 같은&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;소스코드 자동생성을 지원하는 어트리뷰트를 사용할 수 있기 때문에 이러한 문법들도 사용할 수 없게 된다&lt;/p&gt;
&lt;pre id=&quot;code_1712209249756&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 이 역시 사용 불가..
[ObservableProperty]
private string _title;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;조건부&amp;nbsp;컴파일&amp;nbsp;(Conditional&amp;nbsp;Compilation)&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;조건부 컴파일을 통해 특정 버전의 문법을 사용&lt;/span&gt;&lt;/b&gt;하는 것이 가능하다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1712216041162&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#if NET8_0_OR_GREATER
            TestClass testClass = new();
#else
            TestClass testClass = new TestClass();
#endif&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;&lt;i&gt;조건부 컴파일을 통한 문법 활용&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;물론,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;이 예제 코드는 극단적으로 최신 문법을 사용할 수도 있다는 것을 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;확인하기 위한 &lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;예제일 뿐이다&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;특정 버전에서만 동작하는 매우 동적인 기능을 만들기 위해 사용하는 것이 아니라면&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;낮은 버전의 문법을 따라서 작성하는게 맞다고 생각한다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;</description>
      <category>c#/세미나</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/22</guid>
      <comments>https://sslee92.tistory.com/22#entry22comment</comments>
      <pubDate>Wed, 3 Apr 2024 19:05:45 +0900</pubDate>
    </item>
    <item>
      <title>[세미나] Blazor / WPF / MAUI 밋업 (닷넷 버전선택)</title>
      <link>https://sslee92.tistory.com/21</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;닷넷 버전선택&lt;span&gt;&amp;nbsp;&lt;/span&gt;및&lt;/b&gt;&lt;/i&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;닷넷 Standard 버전의 차이점 (2.0 / 2.1)&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;현재 기준의 닷넷버전은 아래와같다&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;.NET Framework 4.8.1&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;.NET 8.0&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 모두 호환되는 플랫폼으로는 Standard가 있다&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;.NET Standard 2.1&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;.NET Standard 2.0&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 호환성의 문제가 있는데,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;.NET Framework&lt;/b&gt;에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;.NET Standard 2.1&lt;/b&gt;을 참조할 수 없다&lt;/span&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 Standard 2.1은 .NET Framework를 제외하고 모두 사용이 가능하다&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;좋은 예시로&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Mvvm을 쓸때 많이 사용하는 누겟패키지중 하나인&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;i&gt;&lt;b&gt;CommunityToolkit.Mvvm&lt;/b&gt;&lt;/i&gt;&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해당 패키지는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;.NET Standard2.0&lt;/b&gt;으로 구현되어있다&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2.1버전에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;.NET Framework&lt;/b&gt;에서의 사용이 불가능 하기 때문에&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2.0 버전을 선택한것으로 유추 해볼 수 있다&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/세미나</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/21</guid>
      <comments>https://sslee92.tistory.com/21#entry21comment</comments>
      <pubDate>Wed, 3 Apr 2024 19:03:51 +0900</pubDate>
    </item>
    <item>
      <title>[세미나] Blazor / WPF / MAUI 밋업 (Application, Current, MainWindow, GetWindow)</title>
      <link>https://sslee92.tistory.com/20</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Application&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;&lt;b&gt;WPF&lt;/b&gt;를 구동시키기 위한 객체인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Application&lt;/b&gt;클래스는 메인으로 실행될&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Window&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;생성 시점을 포함하고 있으며,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;공용 리소스를 등록할 수 있도록 설계되어 있다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;i&gt;&lt;b&gt;OnStartup : 윈도우 생성 시점&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;pre id=&quot;code_1712138147070&quot; class=&quot;cs&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;internal Class App : Application
{
    [STAThread]
    private static void Main(string[] args)
    {
        Window window = new();
        window.ShowDialog();
    }
}​&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;i&gt;&lt;i&gt;&lt;b&gt;Run : 애플리케이션 구동&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;/i&gt;
&lt;pre id=&quot;code_1712138147071&quot; class=&quot;cs&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;internal Class Starter
{
    [STAThread]
    private static void Main(string[] args)
    {
        _ = new App().Run();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;i&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/i&gt;&lt;/blockquote&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;&lt;b&gt;Application&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;인스턴스를 생성하고 이를 구동시키는 것은 아주 간단하다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;&lt;b&gt;Main&lt;/b&gt;과 같은 프로그램 시작점에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;App&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;인스턴스를 생성하고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Run&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;메서드를 호출하기만 하면 된다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Current&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;처음 Application 인스턴스를 생성하고 Run 시점에서 Current가 내부적으로 함께 구성된다&lt;/p&gt;
&lt;pre id=&quot;code_1712138147073&quot; class=&quot;isbl&quot; style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;Application app1 = Application.Current&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;Current는 Static 맴버이며 Application 타입이다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;따라서 형변환을 통해 App으로 사용하는 것도 가능하다&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1712138147074&quot; class=&quot;stata&quot; style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;App app2 = Application.Current as App;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;MainWindow&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;Current와 같은 맥략으로 OnStartup을 통해 실행된 Window 객체 또한&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;별도의 지정 없이도 Current.MainWindow를 통해 가져올 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1712138147075&quot; class=&quot;pgsql&quot; style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;// 기본 윈도우
Window window1 = Application.Current.MainWindow;
// 특정 UI객체로 형변환
JamesWindow window2 = Application.Current.MainWindow as JamesWindow;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;따라서 Application과 Window가 이미 기본 설계에 의해 Singleton으로 등록되어 관리되어 있기 때문에&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;어디서든 Window를 가져올 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;i&gt;GetWindow&lt;/i&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 Window를 찾을 수 있는 더 재밌는 방법도 있다&lt;/p&gt;
&lt;pre id=&quot;code_1712138209916&quot; class=&quot;pgsql&quot; style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;csharp&quot;&gt;&lt;code&gt;Window window = Window.GetWindow(this);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이방법은&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;대상 객체를 기준으로 Window 컨트롤이 나올 때 까지&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;부모 객체를 재귀적으로 찾아 Window 또는 null을 반환하는 기능이다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMqAMT/btsGlxbO07p/Fh6ZABWnUs9BainBzuVPGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMqAMT/btsGlxbO07p/Fh6ZABWnUs9BainBzuVPGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMqAMT/btsGlxbO07p/Fh6ZABWnUs9BainBzuVPGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMqAMT%2FbtsGlxbO07p%2FFh6ZABWnUs9BainBzuVPGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;464&quot; height=&quot;244&quot; data-origin-width=&quot;464&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-alt=&quot;Application과 Window의 Singleton 인스턴스 계층구조&quot; data-lightbox=&quot;lightbox&quot; data-url=&quot;https://blog.kakaocdn.net/dn/UwLCy/btsGlf9yvIW/63S4hSdkj05qrXA4rtRTZ0/img.png&quot;&gt;&lt;/span&gt;Application과 Window의 Singleton 인스턴스 계층구조&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Current / MainWidnow&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;관리 설계&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 이를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;ViewModel&lt;/b&gt;이나&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;CustomControl&lt;/b&gt;에서 직접적으로 사용하는 것은 좋은방법은 아니다&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그 이유는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Application&lt;/b&gt;과&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Window&lt;/b&gt;의 접근으로 인한 관리 포인트가 늘어나기 때문이다&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;따라서,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 직접적인 핸들링 작업을 하기 위한 클래스를 아래&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/i&gt;와 같이 만들어&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Singleton&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;형식으로 관리하여 포인트를 줄이는 것이 현명하다&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;i&gt;예제 : AppManager&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;&lt;/b&gt;
&lt;pre id=&quot;code_1712138272058&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class AppManager
{ 
    // app;
    // AddResource
    // Close
    // GetWindow

    private Application app =&amp;gt; Application.Current;
    public void AddResource(ResourceDictionary resource)
    {
        app.Resources.MergedDictionaries.Add(resourceDictionary);
    }

    public void Close()
    {
        app.Current.MainWindow.Close();
    }

    public Window GetWindow(UIElement element)
    {
        return Window.GetWindow(element);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/세미나</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/20</guid>
      <comments>https://sslee92.tistory.com/20#entry20comment</comments>
      <pubDate>Wed, 3 Apr 2024 18:56:09 +0900</pubDate>
    </item>
    <item>
      <title>[세미나] Blazor / WPF / MAUI 밋업 (WPF 구성 요소)</title>
      <link>https://sslee92.tistory.com/19</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #1f2328; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;WPF 구성 요소&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;WPF의 핵심 DLL들 간의 참조 의존성 관계를 이해&lt;/b&gt;&lt;/span&gt;하는 것은&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;WPF 애플리케이션의 구조를 파악하고, 효율적으로 구성하는 데 큰 도움이 된다&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;클래스의 위치와 필요한 종속성을 알면 개발, 최적화, 문제 해결이 용이해지며&lt;br /&gt;이는 더 견고한 애플리케이션 설계로 이어진다&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;i&gt;&lt;b&gt;WPF 핵심 어셈블리 요소들&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;PresentationFramework.dll&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;PresentationCore.dll&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;WindowsBase.dll&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: left;&quot;&gt;System.Xaml.dll&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2zPFt/btsGl3H6itL/EKKF0VLgBzIJmaemRW3qW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2zPFt/btsGl3H6itL/EKKF0VLgBzIJmaemRW3qW1/img.png&quot; data-alt=&quot;DLL 간의 참조 도식화&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2zPFt/btsGl3H6itL/EKKF0VLgBzIJmaemRW3qW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2zPFt%2FbtsGl3H6itL%2FEKKF0VLgBzIJmaemRW3qW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;210&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DLL 간의 참조 도식화&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;PresentationFramework.dll&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 클래스 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;Border, Canvas, CheckBox, ComboBox, DockPanel, Expander, Grid, Image, ListBox, Menu, ProgressBar, RadioButton, ScrollViewer, Slider, StackPanel, TabControl, TextBlock, ToolBar, TreeView, WrapPanel, Style, DataTemplate, ControlTemplate, ResourceDictionary, Button, Label, MediaElement&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 인터페이스 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;IComponentConnector,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;IStyleConnector&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 열거형 :&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;FontStyle, FontWeight, HorizontalAlignment, VerticalAlignment, TextAlignment, Visibility, Stretch&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 구조체 :&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;CornerRadius, GridLength, Thickness&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;PresentationCore.dll&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 클래스 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;BitmapEffect, BlurBitmapEffect, DropShadowBitmapEffect, BitmapImage, DrawingGroup, GeometryDrawing, ImageBrush, LinearGradientBrush, MatrixTransform, PathGeometry, RenderTargetBitmap, ScaleTransform, SkewTransform, SolidColorBrush, TranslateTransform, VisualBrush&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 인터페이스 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;IRenderInfo, IResourceDictionary, IVisual&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 열거형 :&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;BrushMappingMode, GeometryCombineMode, GradientSpreadMethod, PenLineCap, PenLineJoin, TileMode, TextHintingMode&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 구조체 :&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;Color, Matrix, Point, Rect, Size, Vector&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;WindowsBase.dll&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 클래스 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;Application, CommandManager, DependencyPropertyRegister, DispatcherOperation, DoubleAnimation, KeyGesture, KeyBinding, PropertyChangedEventHandler, RoutedCommand, RoutedEvent, RoutedEventHandler, RoutedUICommand, Timer&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 인터페이스 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;ICommand, INotifyPropertyChanged, INotifyCollectionChanged&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 열거형 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;ComponentResourceKey, DispatcherOperationStatus, ModifierKeys, PropertyChangedEventArgs, UpdateSourceTrigger, DispatcherPriority&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 구조체 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;Duration, Int32Rect&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;System.Xaml.dll&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 클래스 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;XamlSchemaContext, XamlType, XamlMember, XamlDirective, NamespaceMapEntry, XamlNodeList, XamlXmlReader, XamlXmlWriter, MarkupExtension, StaticResourceExtension, BindingExtension&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #fafafa; color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;- 인터페이스 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;&lt;span style=&quot;color: #1f2328; text-align: left;&quot;&gt;IXamlLineInfoConsumer, IXamlLineInfoProvider, IXamlSchemaContextProvider, IXamlObjectWriterFactory, IXamlMember&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이는 각 컴포넌트의 역할과 위치를 명확히 하며, 어떤 기능이 어느&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;DLL&lt;/b&gt;에 포함되어 있는지 알 수 있게 해주어,&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;필요한 클래스와 리소스를 적절히 참조할 수 있게 한다&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;더 나아가, 의존성을 파악함으로써 개발자는 성능을 최적화하고,&lt;br /&gt;발생 가능한 문제를 예측 및 해결하는 데 필요한 깊이 있는 지식을 갖출 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;이러한 이해는 안정적이고 확장 가능하며 유지보수가 쉬운&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;WPF&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;애플리케이션을 설계하는 데 결정적인 요소가 되며,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;결국 사용자에게 더 나은 경험을 제공하는 완성도 높은 소프트웨어로 이어지는 길이다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/세미나</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/19</guid>
      <comments>https://sslee92.tistory.com/19#entry19comment</comments>
      <pubDate>Wed, 3 Apr 2024 18:50:33 +0900</pubDate>
    </item>
    <item>
      <title>[WPF / CefSharp] localStorage(get/set) &amp;amp; script</title>
      <link>https://sslee92.tistory.com/16</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;i&gt;&lt;b&gt;javaScript코드를 날려서 로컬스토리지 값을 읽고 쓰는 로직&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;기본적으로 &lt;i&gt;&lt;b&gt;CefSharp&lt;/b&gt;&lt;/i&gt;의 프레임이 로드 되어야 &lt;i&gt;&lt;b&gt;javaScript&lt;/b&gt;&lt;/i&gt;코드를 실행할 수 있음&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;CefSharp &lt;/b&gt;&lt;/i&gt;의&lt;b&gt;&lt;/b&gt;&lt;i&gt;&lt;b&gt; FrameLoadEnd&lt;/b&gt;&lt;/i&gt;이벤트 또는&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;LoadingStateChanged&lt;/b&gt; &lt;/i&gt;이벤트의 &lt;i&gt;&lt;b&gt;e.IsLoading&lt;/b&gt;&lt;/i&gt;이 &lt;i&gt;&lt;b&gt;false&lt;/b&gt;&lt;/i&gt;일때&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래 함수들을 호출해서 사용&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;LocalStorage Set&lt;/b&gt;&lt;/i&gt;&lt;i&gt;&lt;b&gt;&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1710906367406&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private async void SetLocalStorageData()
{
    string script = @&quot;(function() {
                          localStorage.setItem('키', '값');
                      })();&quot;;

    var result = await browser.EvaluateScriptAsync(script);

    if(result.Success)
    {

    }
    else
    {

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;LocalStorage Get&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1710906667233&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private async void GetLocalStorageData()
{
    string script = @&quot;(function() {
                          var data = localStorage.getItem('키');
                       	  return data;
                      })();&quot;;
                      
    var result = await webView.EvaluateScriptAsync(script);
    
    if(result.Success &amp;amp;&amp;amp; result.Result != null)
    {

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/WPF</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/16</guid>
      <comments>https://sslee92.tistory.com/16#entry16comment</comments>
      <pubDate>Wed, 20 Mar 2024 12:53:43 +0900</pubDate>
    </item>
    <item>
      <title>.NET Framework 그리고 .NET</title>
      <link>https://sslee92.tistory.com/8</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;.NET Framework (닷넷 프레임워크)의 시작&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;닷넷 프레임워크는 2002년 2월 13일, MS(마이크로소프트)가 내놓은 소프트웨어 플랫폼으로,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;객체지향 언어인 &lt;b&gt;c#&lt;/b&gt;과 함께 출시하였다. &lt;br /&gt;&lt;br /&gt;C#언어는 빌드 후 IL(Intermediate Language, 중간 언어)로 변환되어 &lt;br /&gt;CLR(Common Language Runtime, 공통 언어 런타임)에서 실행되는 구조이다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;b&gt;&amp;nbsp; *자바의 바이트코드(Bytecode)와 JRE(Java Runtime Environment, 자바 실행 환경)로 생각하면 된다&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;IL(Intermediate Language, 중간 언어), CLR(Common Language Runtime, 공통 언어 런타임) 이란?&lt;/span&gt;&lt;br /&gt;&amp;nbsp;- https://kukuta.tistory.com/351&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;윈도우용 애플리케이션은 닷넷 프레임워크 기반으로 개발하는 것이 생산성이 높고 성능도 좋다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 애플리케이션 생태계가 웹과 모바일 중심으로 변화하면서 닷넷 프레임워크의 한계가 두드러졌다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;.NET Core (닷넷 코어)&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;MS도 닷넷 프레임워크의 한계를 인식하고 대안을 마련하기 시작했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그 결과 2014년 .NET Core(닷넷 코어)라는 이름으로 크로스플랫폼을 지원하는 오픈소스 프레임워크를 출시했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;.NET 으로 통일&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 더 나아가 2020년 11월 10일, MS는 차세대 애플리케이션 개발플랫폼 .NET(닷넷) 5.0을 공식 발표했다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;동시에 2020년 MS는 닷넷 프레임워크 4.8이 마지막 릴리스라고 발표했다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;173&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/87zIl/btsEjImcYsF/uV9xDmLFWSuZRYyzK2XFT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/87zIl/btsEjImcYsF/uV9xDmLFWSuZRYyzK2XFT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/87zIl/btsEjImcYsF/uV9xDmLFWSuZRYyzK2XFT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F87zIl%2FbtsEjImcYsF%2FuV9xDmLFWSuZRYyzK2XFT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;695&quot; height=&quot;173&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;173&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt; .NET Framework 4.8는 .NET Framework의 최종 버전이며 더 이상의 업데이트는 출시되지 않을 것입니다. 그러나 .NET Framework는 월간 보안 및 안정성 버그 수정 서비스를 계속받을 것입니다. 또한, Windows에 계속해서 포함되어 있으며 삭제할 계획이 없습니다. 기존의 .NET Framework 애플리케이션을 이전할 필요는 없지만 새로운 개발에는 .NET 5.0 이상을 사용하시기를 권장합니다. &lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;그동안 닷넷 프레임워크와 닷넷 코어로 나누어 지원하던 플랫폼을 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;닷넷(.NET)이라는 단일 이름으로 통일하기로 한 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;b&gt;*그 시작 버전이 5.0인 것은 닷넷 코어의 최신 버전이 3.x이고 닷넷 프레임워크의 최신 버전이 4.8인 탓에 &lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;b&gt;개발자 혼란을 줄이기 위해 이 둘을 아우르는 버전을 채택한 것이라고 한다.&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; &lt;span&gt; &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;닷넷 5.0 출시 소식은 개발환경이 대부분 Java인 우리나라에서는 큰 반항을 일으키지는 못했다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;MS의 크로스 플랫폼 전략은 MSA(Microservices Architecture)의 유행 속에서 뒤늦은 감이 있지만 ,&lt;br /&gt;닷넷 5.0 출시로 새로운 전환기를 맞게 되어 서비스 개발을 위한 선택지의 하나로 닷넷도 이름을 올릴 수 있게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;MSA(Microservices Architecture) 란?&lt;br /&gt;&lt;/span&gt;&amp;nbsp;- &lt;a href=&quot;https://www.osckorea.com/post/msa-micro-service-architecture-neun-mueosimyeo-wae-pilyohalggayo&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.osckorea.com/post/msa-micro-service-architecture-neun-mueosimyeo-wae-pilyohalggayo&lt;/a&gt;&amp;nbsp;&lt;/blockquote&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/기타</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/8</guid>
      <comments>https://sslee92.tistory.com/8#entry8comment</comments>
      <pubDate>Tue, 19 Mar 2024 16:49:42 +0900</pubDate>
    </item>
    <item>
      <title>[WPF / CefSharp] 쿠키 확인 및 수정</title>
      <link>https://sslee92.tistory.com/15</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;i&gt;CefSharp에서 개발자도구 열기&lt;/i&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1710829028190&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//여기서 browser는 ChromiumWebBrowser
browser.ShowDevTools();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;F12로 열지 못하고&lt;br /&gt;위 함수를 호출해야 개발자도구가 열림&lt;br /&gt;F12로 열리도록 하려면 아래와같이 추가해야함&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710831013240&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private void Window_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.F12)
    {
        browser.ShowDevTools();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;i&gt;&lt;b&gt;쿠키값 확인&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1434&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7GYUg/btsFWj5r4ru/MTnDWI8xr3ZLfjckIExHd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7GYUg/btsFWj5r4ru/MTnDWI8xr3ZLfjckIExHd0/img.png&quot; data-alt=&quot;CefSharp 개발자도구&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7GYUg/btsFWj5r4ru/MTnDWI8xr3ZLfjckIExHd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7GYUg%2FbtsFWj5r4ru%2FMTnDWI8xr3ZLfjckIExHd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1434&quot; height=&quot;764&quot; data-origin-width=&quot;1434&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CefSharp 개발자도구&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710830574086&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; private async void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
 {
     if (e.Frame.IsMain)
     {
         // 쿠키 관리자에 액세스
         var cookieManager = browser.GetCookieManager();

         // 현재 URL의 모든 쿠키 가져오기
         var cookies = await cookieManager.VisitAllCookiesAsync();

         foreach (var data in cookies)
         {
             if (data.Name == &quot;au_id&quot;)
             {
                 Debug.WriteLine($&quot;이름: {data.Name}, 값: {data.Value}, 도메인: {data.Domain}, path: {data.Path}&quot;);
             }
         }
     }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;쿠키값 변경&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;첫번째방법&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;가져온 쿠키값을 바로 변경&lt;/p&gt;
&lt;pre id=&quot;code_1710830801600&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; private async void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
 {
     if (e.Frame.IsMain)
     {
         // 쿠키 관리자에 액세스
         var cookieManager = browser.GetCookieManager();

         // 현재 URL의 모든 쿠키 가져오기
         var cookies = await cookieManager.VisitAllCookiesAsync();

         foreach (var data in cookies)
         {
             if (data.Name == &quot;au_id&quot;)
             {
                 Debug.WriteLine($&quot;이름: {data.Name}, 값: {data.Value}, 도메인: {data.Domain}, path: {data.Path}&quot;);
		 data.Value = &quot;46ab59d1c8df2f13-60d138d218b3c512c64-3514&quot;;
 		 //data.HttpOnly = true;
 		 await cookieManager.SetCookieAsync(&quot;https://www.mina-gram.com&quot;, data);
             }
         }
     }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;두번째방법&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;새로운 쿠키객체 생성&lt;/p&gt;
&lt;pre id=&quot;code_1710831599936&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; private async void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
 {
     if (e.Frame.IsMain)
     {
         var url = e.Frame.Url;

         // 쿠키 관리자에 액세스
         var cookieManager = browser.GetCookieManager();

         // 현재 URL의 모든 쿠키 가져오기
         var cookies = await cookieManager.VisitAllCookiesAsync();

         #region auid 값 변경            
         // 쿠키 변경
         var cookie = new Cookie()
         {
             Name = &quot;au_id&quot;,
             Value = &quot;46ab59d1c8df2f13-60d138d218b3c512c64-3514&quot;,
             Domain = &quot;.www.mina-gram.com&quot;,
             Path = &quot;/&quot;, // 쿠키 경로
             Expires = null
         };

         await cookieManager.SetCookieAsync(&quot;https://www.mina-gram.com&quot;, cookie);
         #endregion

         foreach (var data in cookies)
         {
             if (data.Name == &quot;au_id&quot;)
             {
                 Debug.WriteLine($&quot;이름: {data.Name}, 값: {data.Value}, 도메인: {data.Domain}, path: {data.Path}&quot;);
             }
         }
     }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/WPF</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/15</guid>
      <comments>https://sslee92.tistory.com/15#entry15comment</comments>
      <pubDate>Tue, 19 Mar 2024 15:18:21 +0900</pubDate>
    </item>
    <item>
      <title>[오류 / WPF / CefSharp] CefSharp.Subprocess 방화벽차단 이슈</title>
      <link>https://sslee92.tistory.com/13</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;오류내용&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;&lt;i&gt;따지고보면 오류는 아니지만&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;&lt;i&gt;사용자입장에서는 보일 필요가 없기 때문에 &lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;&lt;i&gt;오류로 분류함.&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;아래 스크린샷과 같은 방화벽 차단 화면 노출&lt;br /&gt;Windows Defender 방화벽에 의해 CefSharp.BrowserSubprocess가 차단됨 &lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;446&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dn5SEw/btsFob9yuaQ/7ymh6opOkIkNWucKdKsteK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dn5SEw/btsFob9yuaQ/7ymh6opOkIkNWucKdKsteK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dn5SEw/btsFob9yuaQ/7ymh6opOkIkNWucKdKsteK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdn5SEw%2FbtsFob9yuaQ%2F7ymh6opOkIkNWucKdKsteK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;629&quot; height=&quot;446&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;446&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;오류해결&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;CefSettings에 아래코드 추가&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1709531096886&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CefSettings settings = new CefSettings();

// 추가한 코드
settings.CefCommandLineArgs.Add(&quot;disable-features&quot;, &quot;WebRtcHideLocalIpsWithMdns&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;참고자료&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.naver.com/jh4l2656/222406351753&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.naver.com/jh4l2656/222406351753&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/오류</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/13</guid>
      <comments>https://sslee92.tistory.com/13#entry13comment</comments>
      <pubDate>Mon, 4 Mar 2024 14:41:24 +0900</pubDate>
    </item>
    <item>
      <title>[오류 / WPF / CefSharp] 문자열 마무리 현상</title>
      <link>https://sslee92.tistory.com/12</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;오류내용&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;WPF앱내에 CefSharp을 이용한 브라우저 화면에서&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;한글입력시 아래 이미지와 같이 화면 좌측상단에&lt;b&gt; &lt;span style=&quot;background-color: #f6e199;&quot;&gt;[문자열 마무리] 현상이 나타남&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;251&quot; data-origin-height=&quot;135&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KxQLa/btsFbYBUjmE/7654y8rZjD9kaQPKcbnuS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KxQLa/btsFbYBUjmE/7654y8rZjD9kaQPKcbnuS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KxQLa/btsFbYBUjmE/7654y8rZjD9kaQPKcbnuS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKxQLa%2FbtsFbYBUjmE%2F7654y8rZjD9kaQPKcbnuS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;251&quot; height=&quot;135&quot; data-origin-width=&quot;251&quot; data-origin-height=&quot;135&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;오류 원인&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;CEF IME 문제&lt;/b&gt;&lt;/span&gt;였음.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;&lt;i&gt;&lt;span style=&quot;background-color: #fcfcfc; text-align: left;&quot;&gt;IME(input method editor, 입력 방식 편집기)&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;윈도우 고질병이여서 윈도우 설정에서 키보드 설정을하거나,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;Microsoft Office IME 2010를 설치해야한다는 내용만 있어서&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;한참을 찾다가 발견함&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;cef IME, cefsharp IME, wpf cefsharp IME&lt;br /&gt;등으로 검색하면 관련 자료들이 많이 나옴&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;오류 해결&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;아래코드를 넣어주면 끝!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1708582677909&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//여기서 browser는 cefSharp:ChromiumWebBrowser
browser.WpfKeyboardHandler = new CefSharp.Wpf.Experimental.WpfImeKeyboardHandler(browser);​&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;참고한 자료&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;https://github.com/cefsharp/CefSharp/issues/1262&lt;/blockquote&gt;</description>
      <category>c#/오류</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/12</guid>
      <comments>https://sslee92.tistory.com/12#entry12comment</comments>
      <pubDate>Thu, 22 Feb 2024 15:20:11 +0900</pubDate>
    </item>
    <item>
      <title>[c# / 암복호화] DES와 AES</title>
      <link>https://sslee92.tistory.com/11</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;i&gt;&lt;b&gt;DES&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;Data Encryption Standard&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;미국 국립표준기술연구소(NIST)에서 국가 표준으로 정한 암호.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;(1977년에 표준으로 채택)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #202124;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;i&gt;&lt;b&gt;DES&lt;/b&gt;&lt;/i&gt;는 대칭키 암호이며, 56비트의 키를 사용.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;미국 국립표준기술연구소(NIST&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;)에서는&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;&lt;i&gt;&lt;b&gt;DES&lt;/b&gt;&lt;/i&gt;에 대해 5년마다 재평가를 실시하였고,&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;1993년에 실시된 재평가에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;b&gt;DES&lt;/b&gt;&lt;/i&gt;는 안정성에 문제가 있다고 판단함&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;(1998년까지만 표준으로 사용)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;i&gt;&lt;b&gt;AES&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;b&gt;Advanced Encryption Standard&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;DES&lt;/b&gt;&lt;/i&gt;의 안정성 문제로&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;AES&lt;/b&gt;&lt;/i&gt;가 &amp;nbsp;2001년에 NIST에 의하여&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;차세대의 블록 암호화 알고리즘의 표준으로 발표됨&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;&lt;i&gt;&lt;b&gt;AES&lt;/b&gt;&lt;/i&gt;의 암호기술을 사용한 암호문을 해독하려면&lt;br /&gt;양자 컴퓨터로도 30년이상이 걸린다고&lt;b&gt; AES&lt;/b&gt;의 관계자가 주장한 바 있음.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;(&lt;i&gt;&lt;b&gt;DES&lt;/b&gt;&lt;/i&gt;는 1999년에 22시간 15분 안에 해독하는 하드웨어가 만들어짐)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;AES&lt;/b&gt;&lt;/i&gt;는 &lt;b&gt;&lt;i&gt;DES&lt;/i&gt;&lt;/b&gt;와 마찬가지로 대칭키 암호이며,&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;56비트의 키를 사용하는 DES와 달리&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;128, 192, 256비트의 다양한 길이의 키를 사용&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt; 키값이 길면 길수록 보안 공격에 대해 더 유리하게 방어할 수 있다고 함.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;아래코드는 &lt;i&gt;&lt;b&gt;AES256-CBC &lt;/b&gt;&lt;/i&gt;코드.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;margin: 20px 0px; caret-color: auto; background-color: #fafafa; padding: 20px 20px 22px; border: 1px dashed #c5c5c5; color: #333333;&quot; data-ke-type=&quot;moreLess&quot; data-text-more=&quot;AES 암복호화 코드 열기&quot; data-text-less=&quot;AES 암복호화 코드 접기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;pre id=&quot;code_1707893219870&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;   public class AES
   {
       private static string _key = &quot;&quot;;
	   private static string _iv = &quot;&quot;;
       
       /// &amp;lt;summary&amp;gt;
       /// 암호화
       /// &amp;lt;/summary&amp;gt;
       /// &amp;lt;param name=&quot;str&quot;&amp;gt;&amp;lt;/param&amp;gt;
       /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
       public string Encrypt(string str)
       {
           return Encrypt(str, _key, _iv);
       }
       private string Encrypt(string inputText, string key, string iv)
       {
           try
           {
               RijndaelManaged aes = new RijndaelManaged(); //AES 알고리즘
               aes.KeySize = 256;   // 키 크기는 128, 192, 256중에 256
               aes.BlockSize = 128; // 블록 크기는 128고정
               aes.Mode = CipherMode.CBC;
               aes.Padding = PaddingMode.PKCS7;
               aes.Key = CreateKey(key).GetBytes(32); //AES-256을 사용하므로 키값의길이는 32여야 함
               aes.IV = CreateIv(iv).GetBytes(16);    //초기화 벡터는 언제나 길이가 16이어야 함

               // 키값과 초기화 벡터를 기반으로 암호화 작업을 하는 클래스 변수 생성
               var encrypt = aes.CreateEncryptor(aes.Key, aes.IV);

               byte[] xBuff = null;
               using (var ms = new MemoryStream())
               {
                   // encrypt 변수에서 암호화된 데이터를 결과에 쓰는 스트림
                   using (var cs = new CryptoStream(ms, encrypt, CryptoStreamMode.Write))
                   {
                       byte[] xXml = Encoding.UTF8.GetBytes(inputText);
                       cs.Write(xXml, 0, xXml.Length);
                   }

                   xBuff = ms.ToArray();
               }

               String Output = Convert.ToBase64String(xBuff);
               return Output;
           }
           catch (Exception ex)
           {
               return &quot;&quot;;
           }
       }

       /// &amp;lt;summary&amp;gt;
       /// 복호화
       /// &amp;lt;/summary&amp;gt;
       /// &amp;lt;param name=&quot;str&quot;&amp;gt;&amp;lt;/param&amp;gt;
       /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
       public string Decrypt(string str)
       {
           return Decrypt(str, _key, _iv);
       }
       private string Decrypt(string inputText, string key, string iv)
       {
           try
           {
               RijndaelManaged aes = new RijndaelManaged();
               aes.KeySize = 256;
               aes.BlockSize = 128;
               aes.Mode = CipherMode.CBC;
               aes.Padding = PaddingMode.PKCS7;
               aes.Key = CreateKey(key).GetBytes(32);
               aes.IV = CreateIv(iv).GetBytes(16);

               var decrypt = aes.CreateDecryptor();
               byte[] xBuff = null;
               using (var ms = new MemoryStream())
               {
                   using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write))
                   {
                       byte[] xXml = Convert.FromBase64String(inputText);
                       cs.Write(xXml, 0, xXml.Length);
                   }

                   xBuff = ms.ToArray();
               }

               string Output = Encoding.UTF8.GetString(xBuff);
               return Output;
           }
           catch (Exception ex)
           {
               return &quot;&quot;;
           }
       }

       private static Rfc2898DeriveBytes CreateKey(string key)
       {
       	   //키값 생성
           byte[] keyBytes = Encoding.UTF8.GetBytes(key);
           //솔트값(원본 키값을 알기 어렵게 하는 값)
           byte[] saltBytes = SHA512.Create().ComputeHash(keyBytes);

		   //키값에 솔트값을 사용해 새로운 키 생성, 마지막에 들어가는 수는 해시 생성의 반복 횟수이다.
           Rfc2898DeriveBytes result = new Rfc2898DeriveBytes(keyBytes, saltBytes, 100000);    

		   //키값 반환
           return result; 
       }

       private static Rfc2898DeriveBytes CreateIv(string iv)
       {
           //벡터 생성
           byte[] vectorBytes = Encoding.UTF8.GetBytes(iv);
           //솔트값(원본 벡터를 알기 어렵게 하는 값)
           byte[] saltBytes = SHA512.Create().ComputeHash(vectorBytes);

		   //벡터에 솔트값을 사용해 새로운 키 생성, 마지막에 들어가는 수는 해시 생성의 반복 횟수이다.
           Rfc2898DeriveBytes result = new Rfc2898DeriveBytes(vectorBytes, saltBytes, 100000);
			
           //벡터 반환
           return result;
       }
   }&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>c#/기타</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/11</guid>
      <comments>https://sslee92.tistory.com/11#entry11comment</comments>
      <pubDate>Wed, 14 Feb 2024 15:23:20 +0900</pubDate>
    </item>
    <item>
      <title>[c#] 앱을 window 작업표시줄에 고정하기</title>
      <link>https://sslee92.tistory.com/10</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;개발환경&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; c# WPF&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;.NET Framework 4.7.2&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Syspin.exe&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;몇날 며칠을 구글링해서 찾은방법&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;1. TaskbarManager&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;2. 레지스트리&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;3. 작업표시줄 경로에 바로가기 파일 복사 후 작업표시줄 refesh&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt; &lt;span style=&quot;background-color: #fcfcfc; text-align: left;&quot;&gt;경로 :&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #fcfcfc; text-align: left;&quot;&gt;AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar&lt;/span&gt; &lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;세가지 방법 모두 시도하다가 실패하고 찾은방법은&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;syspin.exe를 실행하면서 Argument를 넘겨주면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;작업표시줄에 앱을 고정하거나 해제할 수 있음.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Syspin.exe 설치&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;설치경로&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.technosys.net/products/utils/pintotaskbar&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.technosys.net/products/utils/pintotaskbar&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1707360665801&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Technosys Corporation - Pin To Taskbar&quot; data-og-description=&quot;Windows 7,8,10 Pin To Taskbar Command Prompt Utility. pin to taskbar programmatically windows 10, pin to taskbar programmatically, pintotaskbar Pin To Taskbarx64 Version : 0.99.9.1&amp;nbsp;&amp;nbsp;Release date: Dec 05, 2020 EXE VersionZIP Version&quot; data-og-host=&quot;www.technosys.net&quot; data-og-source-url=&quot;https://www.technosys.net/products/utils/pintotaskbar&quot; data-og-url=&quot;https://www.technosys.net/products/utils/pintotaskbar&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.technosys.net/products/utils/pintotaskbar&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.technosys.net/products/utils/pintotaskbar&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Technosys Corporation - Pin To Taskbar&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Windows 7,8,10 Pin To Taskbar Command Prompt Utility. pin to taskbar programmatically windows 10, pin to taskbar programmatically, pintotaskbar Pin To Taskbarx64 Version : 0.99.9.1&amp;nbsp;&amp;nbsp;Release date: Dec 05, 2020 EXE VersionZIP Version&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.technosys.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;i&gt;앱이 작업표시줄 고정 되어있는지 체크,&lt;/i&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;i&gt;작업표시줄에 앱 고정 및 해제&lt;/i&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;블로그에 올리기는 너무 길어져서 그냥 class 통째로 첨부&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/c6brgI/btsEBWqBX3V/KOV5RNGm1BFfkHRVkpsLJk/SysPin.cs?attach=1&amp;amp;knm=tfile.cs&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;SysPin.cs&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.01MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/기타</category>
      <category>C#</category>
      <category>WPF</category>
      <category>작업표시줄고정</category>
      <category>작업표시줄해제</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/10</guid>
      <comments>https://sslee92.tistory.com/10#entry10comment</comments>
      <pubDate>Thu, 8 Feb 2024 12:34:26 +0900</pubDate>
    </item>
    <item>
      <title>[오류 / WPF / xaml] c00000fd 오류</title>
      <link>https://sslee92.tistory.com/9</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;오류내용&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;xaml 디자이너가 로드되지않고 아래와 같은 오류 발생&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;530&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drnDTg/btsEy6AQY5P/g6e4Fc9y0xznbae6kaINe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drnDTg/btsEy6AQY5P/g6e4Fc9y0xznbae6kaINe0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drnDTg/btsEy6AQY5P/g6e4Fc9y0xznbae6kaINe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdrnDTg%2FbtsEy6AQY5P%2Fg6e4Fc9y0xznbae6kaINe0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;530&quot; height=&quot;258&quot; data-origin-width=&quot;530&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;MainWindow.xaml.cs 생성자&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;InitializeComponent(); 안에서 터져버려서 캐치가 안됐다...&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;한참 구글링을 해본결과 여러가지 문제로 나올 수 있는 오류였다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;오류 원인&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;일단 일반적으로 스택 오버플로우(Stack Overflow)를 나타내는 Windows 운영 체제의 예외 코드이다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;즉, 어디선가 아래와 같은 이유로 &lt;br /&gt;무한루프에 빠져 스택이 너무 많아지거나, 메모리 손상이 생겼다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;1. 무한 재귀 호출&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 재귀 함수가 무한 루프에 빠져 스택 오버플로우를 발생시킬 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;2. 이벤트 핸들러 문제&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;이벤트 핸들러에서 또 다른 이벤트를 발생시켜 무한루프에 빠질 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;3. 데이터 바인딩 문제&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;데이터 바인딩이 무한 루프에 빠져 스택 오버플로우를 유발 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;4. 메모리 누수&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; 메모리 누수가 발생하여 시스템 자원이 고갈되어 스택오버플로우가 발생할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;오류 해결방안&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;해결방법은 간단함&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;그냥 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;어디선가 스택오버플로우가 발생하는 코드를 찾아서 수정&lt;/b&gt;&lt;/span&gt;하면된다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;재귀함수나 무한루프 반복문이 있다면 그걸 먼저 점검 해보는 것을 추천&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, 내 코드를 아무리 뒤져봐도 무한루프라고는 찾아 볼 수가 없었다..&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;재귀함수도 존재하지 않았다..&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;한참 찾았는데&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래 블로그에 올렸던 LogClass에서 터지고 있었음...&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://sslee92.tistory.com/7&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2024.01.05 - [c#/기타] - [c#] 로컬에 로그파일을 남기는 LogClass (싱글톤 구현)&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wBTQH/btsEx6uRGi9/wwn3HiP3ziYG88gdsx2MiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wBTQH/btsEx6uRGi9/wwn3HiP3ziYG88gdsx2MiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wBTQH/btsEx6uRGi9/wwn3HiP3ziYG88gdsx2MiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwBTQH%2FbtsEx6uRGi9%2Fwwn3HiP3ziYG88gdsx2MiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;395&quot; height=&quot;512&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;생성자에서 DeleteOldLogs 함수를 호출하는데&lt;br /&gt;해당 함수에서 로그를 삭제할때 Exception이 발생하였고,&lt;br /&gt;아마도 instance를 호출할때마다 생성자를 새로 생성하다보니&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;계속계속계속 터져나가다가 스택오버플로우가 발생한것같다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;결국 무한루프나 계속 호출되는 재귀함수가 아니더라도&lt;br /&gt;감당되지 않을만큼 터져나가면 발생할 수도 있는듯...&lt;/p&gt;</description>
      <category>c#/오류</category>
      <category>C#</category>
      <category>c00000fd</category>
      <category>c00000fd 오류</category>
      <category>c00000fd오류</category>
      <category>WPF</category>
      <category>WPF c00000fd</category>
      <category>xaml</category>
      <category>xaml c00000fd</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/9</guid>
      <comments>https://sslee92.tistory.com/9#entry9comment</comments>
      <pubDate>Thu, 8 Feb 2024 11:14:28 +0900</pubDate>
    </item>
    <item>
      <title>[WPF / xaml] xaml 코드 자동정렬 설정(Ctrl + K + D)</title>
      <link>https://sslee92.tistory.com/6</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;아주 편리하게 사용하고있는 xaml코드 자동정렬 기능&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;설정이 조금 필요하고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;xaml 코딩 스타일에 따라 오히려 불편할 수도 있음.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;설정방법&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;도구 &amp;rarr; 옵션 &amp;rarr; xaml 검색&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;rarr; 텍스트 편집기 &amp;rarr; XAML &amp;rarr; Formatting &amp;rarr; Spacing&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;rarr; 한 줄에 하나의 특성 배치 체크&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;451&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk9cjx/btsA8LtBtLJ/PV8bbjrjFJ1pG2DIKx8tO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk9cjx/btsA8LtBtLJ/PV8bbjrjFJ1pG2DIKx8tO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk9cjx/btsA8LtBtLJ/PV8bbjrjFJ1pG2DIKx8tO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk9cjx%2FbtsA8LtBtLJ%2FPV8bbjrjFJ1pG2DIKx8tO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;435&quot; height=&quot;451&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;451&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lVhPM/btsA9T5VrBV/iodwVRqaeqGXPJ7qXLNsbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lVhPM/btsA9T5VrBV/iodwVRqaeqGXPJ7qXLNsbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lVhPM/btsA9T5VrBV/iodwVRqaeqGXPJ7qXLNsbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlVhPM%2FbtsA9T5VrBV%2FiodwVRqaeqGXPJ7qXLNsbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;444&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;사용예제&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;위 처럼 설정하고&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;ctrl + K + D를 누르면&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;아래처럼 xaml코드가 한줄에 하나씩 배치됨&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;들여쓰기도 같이됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjdxch/btsEyvOLTHv/aO7XUbPXMYOF7oaqpRJbh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjdxch/btsEyvOLTHv/aO7XUbPXMYOF7oaqpRJbh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjdxch/btsEyvOLTHv/aO7XUbPXMYOF7oaqpRJbh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcjdxch%2FbtsEyvOLTHv%2FaO7XUbPXMYOF7oaqpRJbh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;580&quot; height=&quot;414&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/WPF</category>
      <category>WPF</category>
      <category>xaml</category>
      <category>xaml정렬</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/6</guid>
      <comments>https://sslee92.tistory.com/6#entry6comment</comments>
      <pubDate>Thu, 30 Nov 2023 16:37:48 +0900</pubDate>
    </item>
    <item>
      <title>[c#] Window 기본 브라우저 확인 / 기본 브라우저 실행</title>
      <link>https://sslee92.tistory.com/5</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;윈도우에 설정 되어있는 기본 브라우저 확인&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;현재 윈도우에 &lt;/span&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;기본 브라우저로 설정 되어있는 브라우저를 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;레지스트리에서 확인&lt;/b&gt;&lt;/span&gt;하는 방법&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;b&gt;레지스트리 경로&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;아래 기입된 브라우저 외에 다른 브라우저는 직접 윈도우에서 설정 후 레지스트리 값을 확인&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1701325996596&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//먼저 레지스트리를 다루기 위해서는 Win32 네임스페이스를 참조해야한다
using Microsoft.Win32;

/// &amp;lt;summary&amp;gt;기본브라우저 확인&amp;lt;/summary&amp;gt;
public void CheckDefaultBrowser()
{
	//레지스트리 경로
    //HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice
    const string userChoice = @&quot;Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice&quot;;
    string progId = string.Empty;
    using (RegistryKey userChoiceKey = Registry.CurrentUser.OpenSubKey(userChoice))
    {
        if (userChoiceKey == null)
        {
            //null처리           
        }
        object progIdValue = userChoiceKey.GetValue(&quot;Progid&quot;);
        if (progIdValue == null)
        {
            //null처리
        }
        progId = progIdValue.ToString();
        switch (progId)
        {
            case &quot;IE.HTTP&quot;: //익스플로러
                break;
            case &quot;ChromeHTML&quot;: //크롬
                break;
            case &quot;MSEdgeHTM&quot;: //엣지
            case &quot;AppXq0fevzme2pys62n3e0fbqa7peapykr8v&quot;: //Edge 옛날버전
                break;
            case &quot;WhaleHTM&quot;: //네이버웨일
                break;
            default:
            case &quot;FirefoxURL&quot;:
            case &quot;SafariHTML&quot;:
                break;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;기본 브라우저 실행&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;기본 브라우저 실행은 별게 없음&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp; &amp;nbsp;Process.Start에 url만 넣어주면 윈도우에 설정된 기본 브라우저로 실행됨&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1701326381857&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;   System.Diagnostics.Process.Start(&quot;https://www.naver.com/&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/기타</category>
      <category>C#</category>
      <category>c# 기본브라우저</category>
      <category>C샵</category>
      <category>windws default browser</category>
      <category>기본 브라우저 확인</category>
      <category>레지스트리</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/5</guid>
      <comments>https://sslee92.tistory.com/5#entry5comment</comments>
      <pubDate>Thu, 30 Nov 2023 15:43:39 +0900</pubDate>
    </item>
    <item>
      <title>[c# / Selenium] 개발환경 구축 및 기초</title>
      <link>https://sslee92.tistory.com/4</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;Selenium이란?&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;파이썬, 자바 등 다양한 언어에서 웹 드라이버를 통한 웹 자동화 테스트를 지원하는 라이브러리&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;NuGet패키지 설치&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;- selenium이라고 검색해서 나오는 패키지중 아래 이미지에 나와있는 두가지만 설치&lt;/span&gt;하면 nuget 패키지 설치는 끝이다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp;다른 브라우저를 사용하여 크롤링 할것이라면 해당 브라우저의 드라이버를 검색하면 된다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;950&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crONrK/btrIJ6XCyKK/RhknoROkfUFrWZ0cSp4d0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crONrK/btrIJ6XCyKK/RhknoROkfUFrWZ0cSp4d0k/img.png&quot; data-alt=&quot;NuGet 패키지 관리자&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crONrK/btrIJ6XCyKK/RhknoROkfUFrWZ0cSp4d0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrONrK%2FbtrIJ6XCyKK%2FRhknoROkfUFrWZ0cSp4d0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;950&quot; height=&quot;202&quot; data-origin-width=&quot;950&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NuGet 패키지 관리자&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&amp;nbsp;- 드라이버 설치 시 버전은 해당 브라우저 버전과 같게 설치한다&lt;/span&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KawR6/btrIMCIS5Wo/VyafgdphPHM6KB1s6RLqiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KawR6/btrIMCIS5Wo/VyafgdphPHM6KB1s6RLqiK/img.png&quot; data-alt=&quot;크롬 우측상단 제어버튼(점세개) -&amp;amp;gt; 설정 -&amp;amp;gt; Chrome정보&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KawR6/btrIMCIS5Wo/VyafgdphPHM6KB1s6RLqiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKawR6%2FbtrIMCIS5Wo%2FVyafgdphPHM6KB1s6RLqiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;234&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크롬 우측상단 제어버튼(점세개) -&amp;gt; 설정 -&amp;gt; Chrome정보&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;프로젝트 작성&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;- 프로젝트 생성 후 아래와 같이 using문을 작성한다&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1659427299891&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;웹 페이지 이동&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;아래와 같이 코드를 작성후 실행시키면 크롬브라우저 실행 후 네이버 페이지로 이동하는 것 까지 확인할 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1659427547457&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;IWebDriver driver = new ChromeDriver(); //드라이버생성
//ChromeDriver driver = new ChromeDriver();
//IWebDriver driver = new FirefoxDriver();

driver.Navigate().GoToUrl(&quot;https://www.naver.com/&quot;); //페이지이동&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;첫번째 줄 IWebDriver가 아닌 두번째 줄 ChromeDriver로 객체를 받아줘도 무관하지만&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;IWebDriver의 경우 세번째 줄 처럼 다른 브라우저까지 모두 받아줄 수 있다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Element&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; background-color: #f6e199;&quot;&gt;&amp;nbsp;- 위처럼 드라이버를 생성하고 웹 페이지를 열게 되면 해당 페이지의 HTML element에 접근할 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; background-color: #f6e199;&quot;&gt;&amp;nbsp; &amp;nbsp;원하는 컨트롤의 element에 접근하고 싶다면 해당 컨트롤의 위치 값을 알아야 한다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;443&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOnEQd/btrINLlG3jr/qIzZDwmG0VFGn0KQKyp3j0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOnEQd/btrINLlG3jr/qIzZDwmG0VFGn0KQKyp3j0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOnEQd/btrINLlG3jr/qIzZDwmG0VFGn0KQKyp3j0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOnEQd%2FbtrINLlG3jr%2FqIzZDwmG0VFGn0KQKyp3j0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;926&quot; height=&quot;443&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;443&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위 이미지 처럼 개발자도구(F12)에서 원하는 컨트롤을 찾아 우클릭 후 복사(Copy)에 보면 &lt;br /&gt;&amp;nbsp; &amp;nbsp;selector, xpath등 다양한 방법으로 컨트롤 위치값을 복사 할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659507883712&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;driver.FindElement(By.XPath(&quot;&quot;));
driver.FindElement(By.CssSelector(&quot;&quot;));
driver.FindElement(By.TagName(&quot;&quot;));
driver.FindElement(By.Id(&quot;&quot;));
driver.FindElement(By.Name(&quot;&quot;));&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;복사한 값은 위 코드 빈값에 넣어주면 된다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;버튼 클릭&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위에서 복사한 내용으로 로그인 버튼을 눌러보자&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1659507731605&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;IWebDriver driver = new ChromeDriver(); //드라이버생성
//ChromeDriver driver = new ChromeDriver();
//IWebDriver driver = new FirefoxDriver();

driver.Navigate().GoToUrl(&quot;https://naver.com&quot;); // 네이버 홈
driver.FindElement(By.CssSelector(&quot;#account &amp;gt; a&quot;)).Click(); //클릭이벤트           
//driver.FindElement(By.XPath(&quot;//*[@id='account']/a&quot;)).Click();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;네이버 로그인버튼의 xPath 또는 CssSelector를 복사하여 넣어주고 해당 컨트롤을 클릭&lt;/span&gt;하는 로직이다&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;네이버에 홈에서 로그인버튼을 누르고 로그인 화면으로 이동하는것을 볼 수 있다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;로그인&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;먼저 아이디, 패스워드 컨트롤 id값을 확인하고 해당 컨트롤에 text를 작성한다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Id값으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;element&lt;/span&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;에 접근하고 해당 element에 SendKeys 함수를 이용해 값을 넣어준 뒤&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;위에서 했던 것 처럼 로그인 버튼을 눌러주기만 하면 된다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XUpPr/btrIJ6KIz11/aGvtU926NbwAcSBAxqdaqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XUpPr/btrIJ6KIz11/aGvtU926NbwAcSBAxqdaqK/img.png&quot; data-alt=&quot;로그인화면 개발자도구(F12) id 값 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XUpPr/btrIJ6KIz11/aGvtU926NbwAcSBAxqdaqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXUpPr%2FbtrIJ6KIz11%2FaGvtU926NbwAcSBAxqdaqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;797&quot; height=&quot;128&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;로그인화면 개발자도구(F12) id 값 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1659508592085&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;driver.FindElement(By.Id(&quot;id&quot;)).SendKeys(&quot;입력할 아이디&quot;); //아이디 입력
driver.FindElement(By.Id(&quot;pw&quot;)).SendKeys(&quot;입력할 패스워드&quot;); //패스워드 입력

driver.FindElement(By.XPath(&quot;//*[@id='log.login']&quot;)).Click(); //로그인버튼 클릭&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;i&gt;&lt;b&gt;종합 코드&lt;/b&gt;&lt;/i&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1659509539209&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

IWebDriver driver = new ChromeDriver(); //드라이버생성

driver.Navigate().GoToUrl(&quot;https://naver.com&quot;); // 네이버 홈
driver.FindElement(By.CssSelector(&quot;#account &amp;gt; a&quot;)).Click(); //클릭이벤트

driver.FindElement(By.Id(&quot;id&quot;)).SendKeys(&quot;입력할 아이디&quot;);
driver.FindElement(By.Id(&quot;pw&quot;)).SendKeys(&quot;입력할 패스워드&quot;);

driver.FindElement(By.XPath(&quot;//*[@id='log.login']&quot;)).Click();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;이렇게만 한다면 다른 웹페이지 로그인도 어렵지 않게 진행 할 수 있다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;하지만, 네이버는 크롤링을 제대로 막아 놓은듯 하다... 이방법으로는 로그인이 되지 않는다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;웬만한 사이트 들은 이방법으로 가능하다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>c#/기타</category>
      <category>C#</category>
      <category>selenium</category>
      <category>동적페이지크롤링</category>
      <category>셀레니움</category>
      <category>스크래핑</category>
      <category>웹스크래핑</category>
      <category>웹크롤링</category>
      <category>크롤링</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/4</guid>
      <comments>https://sslee92.tistory.com/4#entry4comment</comments>
      <pubDate>Wed, 3 Aug 2022 15:57:12 +0900</pubDate>
    </item>
    <item>
      <title>웹 크롤링과 웹 스크래핑</title>
      <link>https://sslee92.tistory.com/3</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&amp;nbsp;웹 크롤링, 웹 스크래핑의 차이&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199; font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;웹 크롤링(Web Crawling)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;- 웹페이지의&amp;nbsp;정보들을&amp;nbsp;탐색하고&amp;nbsp;수집하는&amp;nbsp;것&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199; font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;웹 스크래핑(Web Scraping)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;- 특정 웹 사이트나 페이지에서 필요한 데이터를 추출하고 원하는 형태로 가공하는 것&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;개념 자체만 보더라도 크롤링과 스크래핑은 아주 흡사하다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;차이점이 있다면 크롤링(Crawling)은 정보를 수집하는 것에 그치지만&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스크래핑(Scraping)은 수집한 데이터를 추출하고 가공한다는 차이가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; text-align: center;&quot;&gt;스크래핑(Scraping)이 더 큰 범위를 가진다는 것을 알 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하지만, &lt;span style=&quot;font-family: 'Nanum Gothic'; color: #333333; text-align: center;&quot;&gt;둘 중 무엇으로 구글링을 해도 같은 소스들만 나오는것으로 보아&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 둘은 같은 의미로 사용되고 있는거같다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제로 스크래핑을 진행한 여러 회사에서도 모두 크롤링이라고 불렀다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>c#/기타</category>
      <category>C#</category>
      <category>WinForm</category>
      <category>스크래핑</category>
      <category>웹스크래핑</category>
      <category>웹크롤링</category>
      <category>크롤링</category>
      <author>루다대디</author>
      <guid isPermaLink="true">https://sslee92.tistory.com/3</guid>
      <comments>https://sslee92.tistory.com/3#entry3comment</comments>
      <pubDate>Fri, 29 Jul 2022 18:00:31 +0900</pubDate>
    </item>
  </channel>
</rss>