티스토리 뷰

C#/WPF

WPF tutorial - Responding to changes

광그로 2017. 6. 22. 22:12

http://www.wpf-tutorial.com/data-binding/responding-to-changes/



Responding to data source changes


데이터 소스 변경 사항에 대하여 변경 사항을 처리해야할 수도, 하지 않을 수도 있는 두가지의 시나리오가 존재합니다. 

WPF는 ObservableCollectionINotifyPropertyChanged 인터페이스가 있습니다.


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(thisnew PropertyChangedEventArgs(v));
            }
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
    }
}
 
cs

Add user
1.
users.Add(new User() { Name = "New user" });

2.

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(thisnew PropertyChangedEventArgs(v));
            }
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
cs

4.
1
get { return this.name; }
cs




공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함