티스토리 뷰
http://www.wpf-tutorial.com/data-binding/responding-to-changes/
Responding to data source changes
데이터 소스 변경 사항에 대하여 변경 사항을 처리해야할 수도, 하지 않을 수도 있는 두가지의 시나리오가 존재합니다.
WPF는 ObservableCollection과 INotifyPropertyChanged 인터페이스가 있습니다.
1 2 3 4 5 6 7 8 | <DockPanel Margin="10"> <StackPanel DockPanel.Dock="Right" Margin="10,0,0,0"> <Button Name="btnAddUser" Click="btnAddUser_Click">Add user</Button> <Button Name="btnChangeUser" Click="btnChangeUser_Click" Margin="0,5">Change user</Button> <Button Name="btnDeleteUser" Click="btnDeleteUser_Click">Delete user</Button> </StackPanel> <ListBox Name="lbUsers" DisplayMemberPath="Name"></ListBox> </DockPanel> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | namespace WPF_tutorial { /// <summary> /// MainWindow.xaml에 대한 상호 작용 논리 /// </summary> public partial class MainWindow : Window { private List<User> users = new List<User>(); public MainWindow() { InitializeComponent(); users.Add(new User() { Name = "John Doe" }); users.Add(new User() { Name = "Jane Doe" }); lbUsers.ItemsSource = users; } private void btnAddUser_Click(object sender, RoutedEventArgs e) { users.Add(new User() { Name = "New user" }); } private void btnChangeUser_Click(object sender, RoutedEventArgs e) { if (lbUsers.SelectedItem != null) (lbUsers.SelectedItem as User).Name = "Random Name"; } private void btnDeleteUser_Click(object sender, RoutedEventArgs e) { if (lbUsers.SelectedItem != null) users.Remove(lbUsers.SelectedItem as User); } } public class User { public string Name { get; set; } } } | cs |
아무리 눌러도 추가, 수정, 삭제가 안됩니다.
Reflecting changes in the list data source
첫번재 단계는 리스트 소스(ItemSource)의 변화에 반응하여 UI가 응답하도록 하는 것입니다.
private List<User> users = new List<User>();
List<User> 대신 ObservableCollection<User>로 대체하면 간단하게 해결됩니다.
이렇게 하면, 추가와 삭제 버튼은 작동하지만, Change name 버튼은 작동하지 않습니다.
변경사항은 the source list가 아닌 bound data object에서 발생합니다 .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | public partial class MainWindow : Window { private ObservableCollection<User> users = new ObservableCollection<User>(); public MainWindow() { InitializeComponent(); users.Add(new User() { Name = "John Doe" }); users.Add(new User() { Name = "Jane Doe" }); lbUsers.ItemsSource = users; } private void btnAddUser_Click(object sender, RoutedEventArgs e) { users.Add(new User() { Name = "New user" }); } private void btnChangeUser_Click(object sender, RoutedEventArgs e) { if (lbUsers.SelectedItem != null) (lbUsers.SelectedItem as User).Name = "Random Name"; } private void btnDeleteUser_Click(object sender, RoutedEventArgs e) { if (lbUsers.SelectedItem != null) users.Remove(lbUsers.SelectedItem as User); } } public class User { public string Name { get; set; } } | cs |
Reflecting changes in the data objects
두번째 단계는 우리의 커스텀 User class가 INotifyPropertyChanged 인터페이스를 구현하도록 하는 것입니다.
이를 통하여, 우리의 User 객체는 UI 레이어의 변화를 속성에게 알릴 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | using System.ComponentModel; using System.Collections.ObjectModel; 추가해주어야 합니다. namespace WPF_tutorial { /// <summary> /// MainWindow.xaml에 대한 상호 작용 논리 /// </summary> public partial class MainWindow : Window { private ObservableCollection<User> users = new ObservableCollection<User>(); public MainWindow() { InitializeComponent(); users.Add(new User() { Name = "John Doe" }); users.Add(new User() { Name = "Jane Doe" }); lbUsers.ItemsSource = users; } private void btnAddUser_Click(object sender, RoutedEventArgs e) { users.Add(new User() { Name = "New user" }); } private void btnChangeUser_Click(object sender, RoutedEventArgs e) { if (lbUsers.SelectedItem != null) (lbUsers.SelectedItem as User).Name = "Random Name"; } private void btnDeleteUser_Click(object sender, RoutedEventArgs e) { if (lbUsers.SelectedItem != null) users.Remove(lbUsers.SelectedItem as User); } } public class User : INotifyPropertyChanged { private string name; public string Name { get { return this.name; } set { if(this.name != value) { this.name = value; this.NotifyPropertyChanged("Name"); } } } private void NotifyPropertyChanged(string v) { if(this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(v)); } } public event PropertyChangedEventHandler PropertyChanged; } } | cs |
1 2 3 4 5 6 7 8 | set { if(this.name != value) { this.name = value; this.NotifyPropertyChanged("Name"); } } | cs |
3.
"Name"이라는 속성이 변경되었을 때, INotifyPropertyChanged가 가지고 있는
이벤트 속성이 변경되었음을 알리는 PropertyChanged를 발생시킵니다.
1 2 3 4 5 6 7 8 9 | private void NotifyPropertyChanged(string v) { if(this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(v)); } } public event PropertyChangedEventHandler PropertyChanged; | cs |
1 | get { return this.name; } | cs |
'C# > WPF' 카테고리의 다른 글
WPF tutorial - Value conversion with IValueConverter (1) | 2017.06.25 |
---|---|
WPF tutorial - 중간점검 (0) | 2017.06.23 |
WPF tutorial - Using the DataContext, The UpdateSourceTrigger property (0) | 2017.06.22 |
WPF tutorial - Introduction to WPF data binding (0) | 2017.06.22 |
WPF tutorial - The Grid - GridSplitter, A contact form (0) | 2017.06.22 |
- Total
- Today
- Yesterday
- Add TapGesture
- C++
- command
- 코딩야학
- 생활코딩
- 그래프
- 객체
- XAML
- 문자열
- DP
- dfs
- 타일링
- UIView Animation
- Grid
- 스택
- 백준온라인
- 데이터 바인딩
- WPF
- Cell Animation
- CustomCollectionViewCell
- 백준
- BOJ
- listview
- MVVM
- Custom Cell
- FEED
- BFS
- CollectionView
- Fakebook
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |