ListView나 ListBox는 하나의 객체만 바인딩하는게 아니라, 객체의 묶음을 바인딩해야하기 때문에, 데이터 클래스도 저번하고는 좀 다르게 설계해야한다.
그러기 위해서는 다음과 같은 클래스를 상속한다.
[code gutter=”false” language=”csharp”]
class System.Collections.ObjectModel.ObservableCollection<T>
[/code]
사실 저 제네릭클래스는 상속하기만 하면 상관이 없다. 여기서 T는 그냥 데이터만 저장하는 용도로만 사용해도 된다. INotifyPropertyChanged같은 것을 상속하지 않아도 상관이 없다.
테스트로 만들 WPF 어플리케이션은 다음과 같이 생겼다.
ListView | ListBox |
입력상자 |
여기에 사용할 내용은 언제나 그랬듯이 NameCard를 만들 것이다. 이 클래스는 다음과 같이 생겼다.
[code language=”csharp” title=”Model/TestModel.cs”]
using System.Collections.ObjectModel;
namespace BindingTest.Model
{
public class NameCardList : ObservableCollection<NameCard> { }
public class NameCard
{
private string name;
private int age;
private string tag;
public string Name
{
get { return name; }
}
public int Age
{
get { return age; }
}
public string Tag
{
get { return tag; }
}
public override string ToString()
{
return Name;
}
public NameCard(string name, int age, string tag)
{
this.name = name;
this.age = age;
this.tag = tag;
}
}
}
[/code]
ListView나 ListBox에서 직접 바인딩하는 대상은 위에서 말했듯이 NameCardList가 될 것이고, ListViw의 각각의 Column에는 NameCard의 Name, Age, Tag이 위치할 것이다. 굳이 ToString을 오버라이딩 하는 이유는 ListBox가 저걸 사용하기 때문이다.(ListBox는 Column이 나뉘어져 있지 않고, 오로지 객체를 나타내는 string으로 바꿔서 사용한다. 이때 사용하는 메서드가 ToString이다.)
[code language=”xml” title=”MainWindow.xaml#Window”]
<Window x:Class="BindingTest.MainWindow"
…
xmls:model="clr-namepsace:BindingTest.Model"
…
>
[/code]
[code language=”xml” title=”MainWindow.xaml#Window.Resources”]
<Window.Resources>
<model:NameCardList x:Key="MyListKey" />
</Window.Resources>
[/code]
이 위까지는 저번과 비슷하다.
[code language=”xml” title=”MainWindow.xaml#ListView” highlight=”1,4,5,6″]
<ListView Name="ListViewNameCard" ItemsSource="{Binding Source={StaticResource MyListKey}}">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" Width="80" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Age}" Header="Age" Width="80" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Tag}" Header="Tag" Width="80" />
</GridView>
</ListView.View>
</ListView>
[/code]
- Grid.DataContext와 Binding 태그를 이용하지 않고 바인딩을 하는 것이다.(원래 방법을 이용해도 상관없음) ListView나 ListBox는 ItemsSource에 바인딩해야한다.
- 첫번째 Column의 Header 이름은 Name이고, ItemsSource의 개개의 아이템에서 Name이라는 프로퍼티와 바인딩한다.
- 마찬가지로 두번째 Column은 Age이고 ItemsSource 아이템의 Age와 바인딩한다.
- 세번째는 Tag이고 아이템의 Tag와 바인딩한다.
[code language=”xml” title=”MainWindow.xaml#ListBox”]
<ListBox ItemsSource="{Binding Source={StaticResource MyListKey}}" />
[/code]
리스트박스는 Column이 없으므로 그다지 복잡할 게 없다.
[code language=”xml” title=”MainWindow.xaml#InputBox”]
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Label Content="Name : " Margin="5, 5" />
<TextBox Grid.Column="1" Margin="5,5" Name="NameTextBox" />
<Label Grid.Column="2" Margin="5,5" Content="Age : " />
<TextBox Grid.Column="3" Margin="5,5" Name="AgeTextBox" />
<Label Grid.Column="4" Margin="5,5" Content="Tag : " />
<TextBox Grid.Column="5" Margin="5,5" Name="TagTextBox" />
<Button Name="AddButton" Margin="5,5" Grid.Column="6" Click="AddButton_Click">추가</Button>
</Grid>
[/code]
얘도 뭐 딱히 어려울 건 없다. 다음은 버튼의 이벤트핸들러 AddButton_Click를 정의한다.
[code language=”csharp”]
using System;
using System.Windows;
namespace BindingTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void AddButton_Click(object sender, RoutedEventArgs e)
{
Model.NameCardList myList = Resources["MyListKey"] as Model.MyList;
string inputName, inputTag;
int inputAge;
inputName = NameTextBox.Text;
inputTag = TagTextBox.Text;
try
{
inputAge = Convert.ToInt32(AgeTextBox.Text);
}
catch (Exception ex)
{
inputAge = 30;
}
myList.Add(new Model.NameCard(inputName, inputAge, inputTag));
NameTextBox.Text = AgeTextBox.Text = TagTextBox.Text = "";
NameTextBox.Focus();
}
}
}
[/code]
이렇게 해놓으면 입력 후 추가 버튼을 누르면 버튼은 네임카드 리스트에 저장을 하지만, ListView와 ListBox에 자동으로 추가되는 모습을 볼 수 있다.

답글 남기기