푸터 콘텐츠로 바로가기
Iron Academy Logo
C# 애플리케이션
C# 애플리케이션

다른 카테고리

Tim Corey의 토너먼트 뷰어를 통해 설명된 WinForms 데이터 바인딩

Tim Corey
1h 11m 40s

소개

C# App Start to Finish 시리즈의 Lesson 22에서는 Tim Corey가 Tournament Viewer form 작업을 시작하며 WinForms 데이터 바인딩에 집중합니다. Tim은 이 교훈이 데이터베이스나 텍스트 파일에 데이터를 저장하는 것에 관한 것이 아니라고 설명합니다—그것은 나중에 다를 것입니다. 대신, 이 비디오의 전체 목적은 UI를 연결하고, 컨트롤을 채우고, 데이터가 모델과 WinForms 컨트롤 사이에서 데이터 바인딩을 사용하여 어떻게 이동하는지를 이해하는 것입니다.

Tim은 WinForms 데이터 바인딩이 어색하고, 혼란스러우며 때로는 답답할 수 있다고 분명히합니다. 그 때문에, 이 강의는 데이터 바인딩이 실제로 어떻게 동작하는지, 무엇이 그것을 깨뜨리는지, 그리고 어떻게 수정할 수 있는지를 깊이 있고 실질적으로 탐구합니다. Tim의 디버깅 여정을 따름으로써, 우리는 WinForms 바인딩 메커니즘에 대한 현실적이고 가치 있는 이해를 얻습니다.

Tournament Viewer Form 개요

Tim은 Tournament Viewer form이 수행해야 할 작업을 설명하며 시작합니다. 폼은 다음을 표시합니다:

  • 토너먼트 이름

  • 토너먼트 라운드를 포함하는 드롭다운

  • 선택된 라운드의 대진을 보여주는 리스트 박스

  • 선택된 대진의 팀 이름과 점수

팀은 모든 정보가 동기화되어야 한다고 강조합니다. 라운드가 변경되면 대진이 업데이트되어야 합니다. 대진이 변경되면 팀 이름과 점수가 업데이트되어야 합니다. 이 요구 사항이 데이터 바인딩에 대한 전체 논의를 주도합니다. 같은 데이터 소스에 바인딩된 컨트롤(데이터 바운드 컨트롤)은 자동으로 동기화됩니다. BindingNavigator 컨트롤은 레코드 목록의 항목 포인터를 현재로 유지하여 데이터에 대한 바인딩을 처리합니다. CurrencyManager 클래스는 목록 컨트롤과 데이터 소스 객체 간의 바인딩 컬렉션을 관리하여 위치 추적 및 변경 알림을 가능하게 합니다. 텍스트 박스나 레이블과 같은 각 바운드 컨트롤은 이러한 메커니즘을 통해 데이터 소스에 연결되어 자동 동기화를 보장합니다.

토너먼트 객체를 폼에 전달하기

Tim은 토너먼트 뷰어 폼이 어떤 토너먼트를 로드할지를 결정하면 안 된다고 설명합니다. 그 책임은 대시보드에 있습니다. 따라서, 토너먼트 뷰어 폼은 생성자를 통해 TournamentModel을 받아야 합니다.

그는 전달된 토너먼트 객체가 폼 레벨의 비공개 필드에 저장되어 폼의 모든 메서드에서 접근할 수 있도록 하는 방법을 보여줍니다. 이 토너먼트 객체는 모든 데이터 바인딩 작업에 대한 유일한 신뢰 소스가 됩니다. 단순 데이터 바인딩에서는 컨트롤이 단일 데이터 테이블의 값을 포함한 단일 데이터 요소에 바인딩될 수 있으며, 이를 통해 개별 데이터 포인트를 표시하거나 편집할 수 있습니다. BindingSource는 단순 바인딩 및 복잡한 바인딩 시나리오 모두에서 사용할 수 있습니다.

폼 데이터 로드 메서드

Tim은 LoadFormData라는 비공개 메서드를 소개합니다. 이 메서드는 토너먼트 모델에서 데이터를 가져와 UI 컨트롤에 밀어 넣습니다.

예를 들어:

  • 토너먼트 이름 레이블은 tournament.TournamentName에서 직접 값을 얻습니다. 이는 텍스트 박스 컨트롤의 텍스트 속성과 같은 컨트롤의 속성을 데이터 소스의 값으로 설정하는 것을 포함합니다.

Tim은 이것이 가장 간단한 형태의 데이터 바인딩임을 강조하며, 수동으로 값을 할당하는 것으로 리스트 및 컬렉션을 다루기 전에 시작하기에 좋은 점임을 설명합니다. 단순 바인딩은 컨트롤의 단일 속성을 데이터 소스의 단일 값에 연결하며, 일반적으로 한 번에 하나의 레코드를 표시합니다.

대시보드 버튼 연결하기

Tim은 대시보드를 수정하여 사용자가 토너먼트를 선택하고 '토너먼트 로드'를 클릭할 때 토너먼트 뷰어 폼이 열리도록 하는 과정을 설명합니다.

여기서 Tim은 선택된 드롭다운 항목을 TournamentModel로 캐스팅하고 이를 뷰어 폼에 전달합니다. 그는 어플리케이션을 실행하여 토너먼트 이름이 올바르게 나타나는 것을 보고 연결이 잘 되었는지 확인합니다.

이것은 리스트 바인딩에 들어가기 전에 기본 객체 전달과 UI 업데이트가 작동하는 것을 확인합니다.

데이터 소스에서 드롭다운으로 라운드 로드하기

이제 Tim은 리스트 바인딩으로 이동하여 토너먼트 라운드를 시작합니다.

그는 라운드가 문자열보다 정수 리스트로 표현하는 것이 좋다고 설명합니다. Tim은 명시적으로 이 선택이 생활을 더 쉽게 만든다고 말합니다:

  • 정수는 드롭다운에 깔끔하게 바인딩됩니다.

  • 문자열 구문 분석 없이 정수를 검색할 수 있습니다.

  • 선택된 값은 직접 int로 캐스팅할 수 있습니다.

ComboBox 컨트롤은 주어진 테이블 또는 리스트에 바인딩될 수 있어 데이터를 효율적으로 표시하고 선택할 수 있습니다. ComboBox 컨트롤을 바인딩할 때, DisplayMember 속성을 사용하여 사용자에게 표시되는 필드를 지정하고, ValueMember 속성을 사용하여 기본 값으로 사용되는 필드를 결정할 수 있습니다. 마찬가지로, DataGridView 컨트롤도 데이터 테이블에 포함된 정보를 바인딩할 수 있습니다.

Tim은 토너먼트의 라운드를 루프 돌면서 고유한 라운드 번호를 추출하여 리스트에 저장합니다.

데이터 바인딩으로 라운드 드롭다운 연결하기

Tim은 첫 번째 중요한 WinForms 바인딩 규칙을 소개합니다:

항상 DataSource를 재설정하기 전에 null로 설정하세요.

그는 드롭다운의 데이터 소스를 지운 다음 라운드 리스트를 할당합니다. 컨트롤을 데이터 소스에 바인딩하면, 데이터 소스가 INotifyCollectionChanged와 같은 인터페이스를 구현할 경우, 데이터가 변경될 때 컨트롤이 자동으로 UI를 새로고칩니다. 이는 데이터와 그 시각적 표현 사이의 실시간 동기화를 보장합니다. 또한 UI 컨트롤이나 기본 데이터 소스에서의 변경 사항이 설정에 따라 자동으로 바인딩 상대방을 업데이트합니다(단방향 또는 양방향). 정수는 자연스럽게 문자열로 변환되므로, 그는 DisplayMember가 여기 필요하지 않다고 설명합니다.

Tim은 그런 다음 로드 메서드를 호출하는 것을 잊어버리는 일반적인 실수를 보여주고, 하나의 메서드 호출을 놓쳤을 때 어떻게 빈 드롭다운이 발생하는지를 보여줍니다.

SelectedIndexChanged 이벤트 및 동적 업데이트

Tim은 WinForms가 이벤트, 특히 SelectedIndexChanged에 크게 의존한다고 설명합니다.

그는 라운드 드롭다운의 SelectedIndexChanged 이벤트를 선택된 라운드의 대진을 로드하는 메서드에 연결합니다. WinForms 데이터 바인딩에서, 이벤트 핸들러는 이벤트를 발생시킨 컨트롤을 식별하는 객체 발신자 매개변수를 받습니다. Format 및 Parse와 같은 다음 이벤트를 처리하여 데이터 형식 및 유효성을 사용자 정의할 수 있습니다; Binding 클래스의 Format 및 Parse 이벤트는 데이터 바인딩 프로세스 중에 특별한 형식 지정 및 데이터 유효성을 허용합니다. 다른 컨트롤도 유사한 이벤트 처리를 통해 바인딩 및 동기화될 수 있습니다.

Tim은 이벤트 핸들러에 직접 코드를 배치하는 대신 논리를 비공개 도우미 메서드로 추출하는 것을 선호합니다. 그는 이것이 코드를 재사용 가능하게 하고 깔끔하게 유지한다고 설명합니다.

선택한 라운드에 따라 대진 로드하기

Tim은 드롭다운의 선택 항목을 다시 정수로 캐스팅하여 선택된 라운드를 검색합니다.

그는 다시 토너먼트의 라운드를 루프 돌면서 대진 라운드가 선택된 라운드와 같은 대진을 필터링합니다. 이러한 대진은 선택된 대진 리스트에 배치되며, 이 리스트는 대진 리스트 박스의 데이터 소스가 됩니다.

이것은 복잡한 객체 리스트를 바인딩하는 도전을 소개합니다.

바인딩을 위한 디스플레이 속성 만들기

Tim은 대진 모델에 UI 표시를 위한 자연스러운 문자열 표현이 없다고 설명합니다.

UI에 논리를 강제하는 대신, Tim은 모델에 읽기 전용 DisplayName 속성을 추가합니다. 이 속성은 다음과 같은 문자열을 만듭니다:

팀 A 대 팀 B

팀이 없는 경우(부전승이나 향후 라운드), Tim은 다음을 반환합니다:

대진이 아직 결정되지 않음

Complex 바운드 컨트롤, 예를 들어 DataGridView는 데이터 테이블 또는 다른 구조의 여러 데이터 요소를 표시 및 편집할 수 있는 복잡한 바인드 시나리오를 지원합니다. 복잡한 데이터 바인딩을 통해 여러 데이터 요소를 컨트롤에 바인딩할 수 있으며, 기본 레코드 소스에서 여러 열 또는 행을 바인딩할 수 있습니다. ADO.NET은 DataTable, DataView 같은 바인딩에 적합한 많은 데이터 구조를 제공하며, Windows Forms는 여러 데이터 소스에 바인딩을 지원합니다. 바인딩 클래스는 데이터 소스 필드와 컨트롤 속성 간의 논리적 연결을 관리하며, IBindingList, IEditableObject, INotifyPropertyChanged와 같은 인터페이스는 정렬, 변경 알림 및 롤백 지원을 제공합니다. 데이터가 표시되는 방식을 제어하기 위해 데이터 뷰에 기본 필터를 설정할 수 있으며, 바인딩 컨텍스트와 CurrencyManager는 데이터 바운드 컨트롤이 동기화되는 방식을 궁극적으로 결정합니다. Windows Form의 BindingContext 속성은 폼에 대한 CurrencyManager 객체를 관리하며, 각각의 데이터 소스는 하나의 CurrencyManager 객체를 가지고 있으며 같은 데이터 소스에 바인딩된 모든 컨트롤을 동기화시킵니다. Windows Forms에서 표준 데이터 바운드 컨트롤처럼 동작하는 사용자 정의 컨트롤을 만들 수 있으며, 이는 필요한 데이터 바인딩 인터페이스를 구현하여 가능합니다.

Tim의 WinForms 데이터 바인딩 원칙 중 핵심으로 강조되는 것은:

모델이 그 자신을 어떻게 표시할지를 결정해야 하며, UI가 아닌 것입니다.

바인딩 버그 디버깅하기

Tim은 여러 버그를 발견합니다:

  • 라운드 2가 올바르게 표시되지 않음

  • 대진이 새로고침되지 않음

  • 이벤트가 예상치 못하게 발생함

이 문제를 숨기기보다는, Tim은 각 디버깅 단계를 설명합니다. 그는 리스트가 교체될 때 바인딩이 어떻게 깨지는지 설명하며, 새 리스트가 유효한 데이터를 포함하고 있어도 그렇다고 합니다.

이는 중요한 WinForms 레슨으로 이어집니다.

다음 코드는 데이터 바인딩 프로세스 중에 특별한 형식 지정 및 유효성을 제공하기 위해 Binding 클래스의 Format 및 Parse 이벤트를 처리하는 방법을 설명합니다. Format 이벤트와 Parse 이벤트는 UI와 데이터 소스 간의 데이터가 변환되고 검증되는 방식을 사용자 정의하는 데 사용할 수 있습니다.

Windows Forms 데이터 바인딩에서 BindingSource vs BindingList

Tim은 BindingSource를 사용하여 UI 컨트롤과 데이터 사이에 배치하며 실험합니다. 그는 이것이 권장되는 접근 방식이었지만, 복잡성과 혼란을 불러일으킨다고 설명합니다. BindingSource 컴포넌트는 데이터 소스와 Windows Forms 컨트롤 간의 프록시 역할을 하며, DataTables, DataViews, BindingLists, 배열 등 다양한 바인딩에 적합한 데이터 구조와 함께 작동합니다.

그리고 나서 그는 BindingList를 소개하여 리스트가 변경될 때 자동으로 바운드 컨트롤을 업데이트한다고 설명합니다. 데이터 소스가 적절한 인터페이스(예: INotifyCollectionChanged)를 구현할 경우, Windows Forms의 데이터 바인딩은 기본 데이터가 변경될 때 컨트롤의 자동 업데이트를 지원합니다.

그러나, Tim은 중요한 규칙을 발견합니다:

BindingList를 새로운 것으로 교체해서는 안 됩니다.

대신에, 당신은:

  • 기존 BindingList를 지우세요

  • 항목을 다시 추가하세요

리스트를 교체하는 것은 바인딩 연결을 깨뜨립니다.

리스트를 지워서 손상된 바인딩 수정하기

Tim은 바인딩 문제의 근본 원인을 확인합니다:

  • 새로운 BindingList() 할당하는 것은 UI를 연결 해제합니다

  • 항목을 지우고 다시 추가하면 바인딩이 유지됩니다.

그는 이 패턴을 사용하여 라운드와 대진 전부를 업데이트합니다. 일관되게 적용한 후, UI는 마침내 올바르게 업데이트됩니다.

초기 선택 항목 수동으로 로드하기

Tim은 WinForms가 항목을 로드할 때 SelectedIndexChanged를 자동으로 실행하지 않음을 설명합니다.

이를 수정하기 위해, 그는 수동으로:

  • 라운드를 로드한 후 라운드 1 대진을 로드합니다.

  • 프로그램적으로 첫 번째 대진을 선택합니다.

이는 사용자 상호 작용 없이 UI가 올바르게 초기화되도록 보장합니다.

최종 결과 및 레슨 요약

레슨이 끝날 즈음, Tim은 확인합니다:

  • 라운드는 올바르게 업데이트된다

  • 대진은 올바르게 업데이트된다

  • 팀 이름과 점수는 적절히 로드된다

  • 부전승과 향후 라운드는 의미 있는 텍스트로 표시된다

그는 이 레슨이 완벽함이 아닌, WinForms 데이터 바인딩이 실제로 어떻게 동작하는지 또는 그 한계까지의 이해에 관한 것임을 강조합니다.

Tim은 점수 및 필터링(예: '미플레이만')이 다음 레슨에서 실질적인 상태 변화를 다룰 때 처리될 것이라고 설명하면서 마무리합니다.

마무리 생각

23강의 'C# 앱 시작부터 끝까지' 시리즈에서, Tim Corey는 실시간으로 모든 실패, 수정 및 설계 결정을 수행하면서 WinForms 데이터 바인딩에 대한 실용적인 강의를 제공합니다.

Tim의 비디오를 따라가면 개발자들은 현실적인 이해를 얻게 됩니다:

  • WinForms 바인딩이 왜 불안정해 보이는지

  • BindingList가 어떻게 작동하는지

  • 리스트를 지우는 것이 왜 중요한지

  • UI와 모델이 어떻게 상호작용해야 하는지

WinForms 데이터 바인딩으로 어려움을 겪은 적이 있다면, 이 레슨과 Tim의 설명은 '왜'라는 부분이 마침내 명쾌해집니다.

Hero Worlddot related to Tim Corey의 토너먼트 뷰어를 통해 설명된 WinForms 데이터 바인딩
Hero Affiliate related to Tim Corey의 토너먼트 뷰어를 통해 설명된 WinForms 데이터 바인딩

사랑하는 것을 공유하여 더 많은 수익을 얻으세요

당신은 .NET, C#, Java, Python, 또는 Node.js를 다루는 개발자를 위한 콘텐츠를 만드나요? 당신의 전문성을 추가 수입으로 전환하세요!

아이언 서포트 팀

저희는 주 5일, 24시간 온라인으로 운영합니다.
채팅
이메일
전화해