프로그래밍/Windows Phone7

Windows Phone 7-ListBox 컨트롤 사용법과 데이타 바인딩 개념 설명

Terry Cho 2010. 8. 17. 08:00


지금까지 대강 윈폰7의 프로그래밍 개념에 대해서 잡아봤고, 오늘은 약간 더 실제 프로그래밍을 하는데 필요한 부분에 대해서 알아봅니다.
스마트폰 애플리케이션을 개발하는데, 가장 많이 사용되고 필수적인 컨트롤은 ListBox 컨트롤입니다. 전화번호 목록, 이메일 목록, 상품 목록등 각종 목록을 표시하는데 필수적으로 사용됩니다. 이번에는 이 ListBox 컨트롤의 사용방법에 대해서 알아보고, 아울러 상당히 중요한 데이터 바인딩 개념에 대해서 소개합니다.

 
오늘 만들어볼 예제 화면입니다. 위의 두개의 텍스트 박스가 있고, 왼쪽에는 이름을 오른쪽에는 이메일을 넣습니다. 그후에 Add 버튼을 누르면 아래 리스트에 추가되고, 아래 리스트에서 아이템을 선택한후에 Remove 버튼을 누르면 삭제되는 아주 간단한 애플리케이션입니다.
데이터 구조는 상당히 간단합니다. Contact이라는 ValueObject가 Name과 Email이라는 속성을 가지고 있고, 이 Contact이라는 ValueObject를 List형태로 저장한 것이 데이터 모델입니다.
Contact Class를 먼저 살펴보면

형태입니다. 간단합니다.
다음으로 UI를 디자인합니다.
TextBox와 Button등을 배열하고, 가장 중요한 ListBox를 추가합니다.

대충 이런식으 코드가 됩니다.
이제 ContactList를 정의할 클래스를 지정하고, ContactList를 List형태로 생성합니다.

List<Contact> contacts = new List<Contact>();

이런 식으로요. 그런데, 이런식으로 코딩을 하고 나중에 수행을 해보면, 아무리 Add나 Remove 버튼을 눌러도 화면에는 새로운 Contact이 추가되거나 삭제되지 않습니다. 왜냐? ListBox UI콘트롤과 이 contacts 변수가 바인딩되서 ListBox는 이 contacts 내부의 내용을 출력하게 되는데, ListBox 컨트롤은 contacts 변수에 값이 추가되는지 안되는지를 모르기 때문입니다. 그래서 contacts 리스트에 데이터가 추가되거나 삭제 되면 이를 ListBox 컨트롤에 알려줘야 하는데, 이렇게 List 형태에서 데이터가 추가되거나 삭제될 때 연결된 UI 컨트롤에 이벤트를 발생해서 전달해주는 클래스로 “ObservableCollection” 가 있습니다.
그래서 contacts를 생성할때는 다음과 같이 해줘야 합니다.

ObservableCollection <Contact> contacts = new ObservableCollection<Contact>();

그리고, Add 버튼이 눌렸을 때 새로운 Contact을 추가하고, Remove를 눌렀을 때 현재 선택된 List 아이템을 삭제하는 코드를 추가합니다. 추가한 MainPage.xaml.cs 내용은 다음과 같습니다.

Add 버튼 클릭에서는 단순히 contacts에 새로운 Contact 객체를 생성해서 Add해주고, Remove는 ListBox :: SelectedIndex라는 메서드를 이용해서 현재 선택되어 있는 아이템 번호를 읽어오고, 그것을 RemoveAt 메서드를 이용해서 지웁니다. 앞에 if문으로 SelectedItem이 null인지 체크하는 것은 예를 들어 현재 3개의 아이템이 있는데, 3번째것을 삭제하고 나면 선택 포커스가 그대로 3번째를 가르킵니다. 3번째를 삭제했는데도 말이지요. 그래서 만약 사용자가 선택을 1,2번째로 바꾸지 않고 그대로 Remove 버튼을 눌러서 삭제하면 Null Pointer Error가 납니다. (3번째 선택에는 아이템이 없기 때문에 삭제할 수 없기 때문에. 말로 설명이 잘 안되는데, 직접 한번 테스트 해보시기를.)
그리고 가장 중요한 것 ListBox UI 컨트롤에 어디서 데이터를 가지고 올지 알려줍니다.

contactListBox.ItemsSource = contacts;

이 말은 ListBox에 데이터를 contacts라는 List형 변수에서 가지고 오라는 이야기입니다. 이것이 데이터 바인딩인데, 이건 조금 있다 설명하기로 하고
자아 끝났습니다. 실행을 하면? 예상과 다른 결과가 나타납니다.


우리가 원하는 것은 contacts 안에 있는 Contact 객체들의 내용 즉 이름과 이메일을 보고 싶은데 생뚱 맞게, ListBoxSample.Contact 들이 목록으로 쭈욱 나옵니다. 그도 그럴것이 ListBox 컨트롤은 Contacts 형태의 리스트만을 가지고 있는 contacts라는 변수만 바인딩을 했을뿐, 실제 Contacts 안의 데이터를 어떻게 나타내야 할지를 모릅니다.
이제 ListBox에게 실제Contacts 객체를 얻어왔을 때 어떻게 데이터를 출력할지를 알려줍니다.MainPage.xml을 다음과 같이 수정합니다.

• 먼저 ListBox에 각각의 아이템을 어떻게 출력하는지를 정의하기 위해서 Template을 정의합니다. ListBox.ItemTemplate이 각각의 아이템을 어떤 형태로 출력할지를 정의하는 겁니다.
• 우리는 데이터를 contacts라는 객체에서 가지고 올것이기 때문에 DataTemplate을 정의하고, 각 하위 엘리먼트에서 contacts의 Item인 Contact 객체의 Attribute (Name,Email)을 각각의 TextBox에 추가하도록 한다.
• ListBox에서 ItemSource를 contacts를 정의했기 때문에, TextBox에서 “{Binding Name}”은 이런식으로 해석된다 DataTemplate에 의해서 contacts의 각각의 아이템이 선택되고 (Contact) 객체, 거기에 {Binding Name}에 의해서 Contact.Name 값이 뽑아지게 된다.
다시 이 개념을 정리해 보면

사실 이 포스트에서의 핵심은 ListBox와 List<> 클래스를 어떻게 바인딩하느냐가 핵심이다. 물론 ListBox 컨트롤 사용법을 알리는것도 목적이 있지만, 이 부분이 상당히 헷갈릴 수 있씁니다., (필자는 여기서 좀 헤맸습니다...) 그래서 다음 포스팅에서는 데이터 바인딩의 개념에 대해서 조금 더 자세하게 설명해보도록 하겠습니다.

참고 : 소스 코드

그리드형