WPF, XAML

(동영상)C#, WPF 데이터바인딩 실습, INotifyPropertyChanged 인터페이스, PropertyChanged …

(동영상)C#, WPF 데이터바인딩 실습, INotifyPropertyChanged 인터페이스, PropertyChanged 이벤트를 이용한 데이터 바인딩 

a346afdaa2907ab86394a8233bab7097_1597635

 n  데이터바인딩에서 소스 객체는 UI 컨트롤 일수도 있지만 위 그림처럼 소스 객체가 C#의 일반 클래스가 될 수도 있는데 이 경우 프로퍼티(속성)의 값이 변경되는 경우 이를 타겟 객체에 알릴 수 있는 메커니즘이 필요 합니다.

n  WPF 데이터 바인딩은 이벤트가 INotifyPropertyChanged 인터페이스를 구현한 클래스안에 정의되어 있으면 이벤트를 찾는데 소스 객체의 속성값의 변경을 통지하기 위해서는 이 인터페이스를 상속받아 구현하고 PropertyChangedEventHandler 델리게이트를 기본으로 하는 PropertyChanged 이벤트를 정의해야 합니다.

n  PropertyChanged 이벤트를 발생시킬 때의 처음 인자는 this이며 두번째 인자는 PropertyChangedEventArgs 타입의 객체 입니다. PropertyChangedEventArgsstring 타입의 PropertyName 이라는 프로퍼티가 정의되어 있는데 프로퍼티를 구별하기 위해 사용합니다. 그래서 PropertyChangedEventArgsnew 하면서 프로퍼티 이름을 넣어 줍니다.

n  CallerMemberName특성(Attribute)을 통해 어느 프로퍼티(속성)에서 PropertyChanged 이벤트가 발생했는지 확인 가능 합니다. 만약 CallerMemberName 특성(Attribute)이 없으면 프로퍼티(속성) 이름을 문자열로 지정해야 합니다.

public void RaisePropertyChange([CallerMemberName] string propertyname = null)        {

if (PropertyChanged != null)

{

PropertyChanged(this, new PropertyChangedEventArgs(propertyname));

}

// PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));

}

n  이 방법이 다수의 프로퍼티를 다루는 좋은 방법 입니다. 하나의 PropertyChanged 이벤트가 모든 프로퍼티(속성)에 대한 변경을 처리할 수 있기 때문 입니다.

 

[INotifyPropertyChanged 인터페이스를 이용한 데이터 바인딩 실습]

 

프로젝명 : WpfApp8 

 

실습개요

-         User 모델을 상속받은 ViewModel 객체가 데이터바인딩의 소스 객체가 되고 이것이 UI TextBox컨트롤과 데이터바인딩이 이루어 지는데 최초 ViewModel에서 LastName, FirstName

-         KIM, KIL_DONG으로 셋팅하고 값이 UI 컨트롤에 표시됩니다. “이름변경버튼을 클릭하면 ViewModel에서 LastName, FirstName 홍길동으로 변경하는데 이것이 UI 컨트롤에 데이터바인딩 되어 UI TextBox 컨트롤에 표시됩니다.

 

 

[MainWindow.xaml]

<Window x:Class="WpfApp8.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:local="clr-namespace:WpfApp8"

        mc:Ignorable="d"

        Title="MainWindow" Height="178.916" Width="556.024">

    <Grid HorizontalAlignment="Left" Height="150" VerticalAlignment="Top" Width="546" Margin="0,0,0,-0.4">

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="205*"/>

            <ColumnDefinition Width="341*"/>

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <RowDefinition/>

            <RowDefinition/>

            <RowDefinition/>

        </Grid.RowDefinitions>

        <Label x:Name="label" Content="First Name" HorizontalAlignment="Left" Margin="34,10,0,0" VerticalAlignment="Top" Height="26" Width="98"/>

        <Label x:Name="label1" Content="Last Name" HorizontalAlignment="Left" Margin="34,14.4,0,0" Grid.Row="1" VerticalAlignment="Top" Height="26" Width="98"/>

        <TextBox x:Name="textBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="21.2,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="283" Text="{Binding FirstName}"/>

        <TextBox x:Name="textBox1" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="21.2,14.4,0,0" Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Top" Width="283" Text="{Binding LastName}"/>

        <Button x:Name="button" Content="보기" Grid.Column="1" HorizontalAlignment="Left" Margin="21.2,10,0,0" Grid.Row="2" VerticalAlignment="Top" Width="127" Height="30" Click="Button_Click"/>

        <Button x:Name="button1" Content="이름변경" Grid.Column="1" HorizontalAlignment="Left" Margin="180.2,10,0,0" Grid.Row="2" VerticalAlignment="Top" Width="124" Height="30" Click="Button1_Click"/>

    </Grid>

 

</Window>

 

 

[MainWindow.xaml.cs]

 

using System.Windows;

 

namespace WpfApp8

{

public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

            ViewModel v = new ViewModel();

            this.DataContext = v;

        }

 

        private void Button_Click(object sender, RoutedEventArgs e)

        {

            ViewModel v = this.DataContext as ViewModel;

            MessageBox.Show(v.LastName + "," + v.FirstName);

        }

 

        private void Button1_Click(object sender, RoutedEventArgs e)

        {

            ViewModel v = this.DataContext as ViewModel;

            v.FirstName = "길동";

            v.LastName = "";

        }

    }

}

 

 

[User.cs]

 

using System.ComponentModel;

using System.Runtime.CompilerServices;

 

namespace ApfApp8

{

    public class User : INotifyPropertyChanged

    {

        private string _firstName;

        public string FirstName

        {

            get

            {

                return _firstName;

            }

            set {

                _firstName = value;

                RaisePropertyChange();

            }

        }

 

        private string _lastName;

        public string LastName

        {

            get

            {

                return _lastName;

            }

            set

            {

                _lastName = value;

                RaisePropertyChange();

            }

        }

 

        public event PropertyChangedEventHandler PropertyChanged;

 

 

        public void RaisePropertyChange([CallerMemberName] string propertyname = null)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyname));

            }

            // PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));

        }

 

    }

}

 

 

[ViewModel.cs]

 

using ApfApp8;

 

namespace WpfApp8

{

    class ViewModel : User

    {

        public ViewModel()

        {

            FirstName = "KIL-DONG";

            LastName = "KIM";

        }

    }

}

 d69b747491bbd351ea7c41c6b42f4470_1597633


 

Comments