ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • WPF MVVM 패턴을 이용한 앱 만들기(MVVM패턴 예제)
    프로그래밍/C# 2019. 11. 2. 12:42
    반응형

    안녕하세요 까치 입니다.

    Visual Studio 를 다운 받아서 WPF를 공부를 하면서

    WPF는 MVVM패턴을 이용하기가

    최적화 되어있다는 것을 알 수 있었습니다.

    MVVM패턴을 어떻게 이용할 것 인가 에 

    대해 고민을 엄청 나게 많이 했는데요.

    MVVM패턴을 어떻게 적용할 

    것인가에 대해 

    포스팅을 해 보겠습니다.

     

    먼저, 폴더를 만들어 파일을 나눠줍니다.

    1. ViewModel(= StudentViewModel.cs)

    2. MainWindow(= MainWindow.cs)

    3. Model(= StudentFactory.cs)

    처음 보실 부분은 mainWindow입니다.

    아무런 내용이 없습니다.

    MVVM패턴에는 윈도우cs는 사용하지 않는 것이 좋습니다.

    구현을 할려고 하면 ViewModel의 데이터가 연동이 되지 않아 

    더 복잡해 지더라구요 

    그래서 컨트롤 하는 부분은 ViewModel에서 처리하시는 것이 좋습니다.

    DataContext로 ViewModel과 연동을 지어지는 부분이 있는데

    사용 하셔도 되고 안하셔도 됩니다.

     

    이제 오늘 제일 중요한 Model 데이터 베이스와 연동 되는 부분입니다.

     

     public class StudentFactory
        {
            ObservableCollection<Student> students = new ObservableCollection<Student>();
            public ObservableCollection<Student> GetAllStudent()
            {
    
                students.Add(new Student() { Grade = "1", Cclass = "3", Name = "홍길동", No = "1010", Score = "A" });
                students.Add(new Student() { Grade = "2", Cclass = "2", Name = "이남길", No = "1020", Score = "B" });
                students.Add(new Student() { Grade = "1", Cclass = "1", Name = "이상이", No = "1030", Score = "A" });
                students.Add(new Student() { Grade = "3", Cclass = "4", Name = "김종국", No = "1040", Score = "D" });
                students.Add(new Student() { Grade = "1", Cclass = "5", Name = "김석봉", No = "1050", Score = "B" });
                students.Add(new Student() { Grade = "2", Cclass = "2", Name = "주씨", No = "1060", Score = "C" });
    
                return students;
            }
        }
    
        public class Student : Notifier 
        {
            private string grade;
            private string cclass;
            private string no;
            private string name;
            private string score;
    
            public string Grade
            {
                get { return grade; }
                set
                {
                    grade = value;
                    OnPropertyChenaged("Grade");
                }
            }
            public string Cclass
            {
                get { return cclass; }
                set
                {
                    cclass = value;
                    OnPropertyChenaged("Cclass");
                }
            }
            public string No
            {
                get { return no; }
                set
                {
                    no = value;
                    OnPropertyChenaged("No");
                }
            }
            public string Name
            {
                get { return name; }
                set
                {
                    name = value;
                    OnPropertyChenaged("Name");
                }
            }
            public string Score
            {
                get { return score; }
                set
                {
                    score = value;
                    OnPropertyChenaged("Score");
                }
            }
    
    
        }

     

    notifier는 이렇게 구성했습니다.

     public class Notifier : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChenaged(string property)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
            }
        }

    보기만 해도 코딩을 잘 정리 했네요.

    이부분은 MVVM일주일 만에배우기라는 책를 인용햇습니다.

    참고 하세요 

     

    자 이제 화명을 볼 차례입니다 먼저 데이터를 만들고 

    화명을 보면 되는데 화면에 어떻게 처리를 해줄까 하는 생각을

    많이 하셔야 됩니다.

    ViewModel을 이해하셔야 View처리도 깔끔히 되는데요.

    화면 구성을 살펴보고 ViewModel을 보시겠습니다.

    위에는 화면입니다. 화면은 간단히 

    DataGrid와 

    Textbox를 이용하여 만들었습니다.

    Read는 Factory에서 만든 데이터를 불러 올 용도로 사용할 예정입니다.

    <Window
            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:WPF_CodingTest"
            xmlns:ViewModel="clr-namespace:WPF_CodingTest.ViewModel" x:Class="WPF_CodingTest.MainWindow"
            //xml이란 부분은 java에선 import, c#에선 using 부분입니다. 
            // 이부분을 삽입 해줘야 연결이 되고 model의 객체들을 사용할 수 있습니다.
            // 꼭 xml에 대해 공부해주세요.
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="585" Loaded="Window_Loaded">
        <Grid Margin="0,0,3.4,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition Width="0*"/>
            </Grid.ColumnDefinitions>
    		//그리드 정의
            <DataGrid x:Name="datagrid1"
                      ItemsSource="{Binding FoundStudents}"  //viewModel의 객체 바인딩
                      SelectedItem="{Binding SelectedStudent, Mode=TwoWay}" //xml에서 이벤트를 자동으로 처리하여 selec된 객체를 삽입해줌
                      SelectionUnit="FullRow"
                      Margin="10,10,189.2,10" />
            <Border DataContext="{Binding SelectedStudent}"
                    Margin="0,10,8.2,10"
                    HorizontalAlignment="Right"
                    Width="162"
                    Background="#66FFFFFF">
                <StackPanel Margin="10">
                    <TextBlock Text="Student"
                            FontWeight="Bold"
                            FontSize="16"
                            HorizontalAlignment="Center"
                            Margin="10" />
                    <TextBlock Text="Grade" />
                    <TextBox Text="{Binding Grade, Mode=TwoWay}" />
                    <TextBlock Text="Cclass" />
                    <TextBox Text="{Binding Cclass, Mode=TwoWay}" />
                    <TextBlock Text="No" />
                    <TextBox Text="{Binding No, Mode=TwoWay}" />
                    <TextBlock Text="Name" />
                    <TextBox Text="{Binding Name, Mode=TwoWay}" />
                    <TextBlock Text="Score" />
                    <TextBox Text="{Binding Score, Mode=TwoWay}" />
                </StackPanel>
            </Border>
            //함수를 ViewModel에서 사용하기 위해 작성해줌 
            <Button Command="{Binding ReadCommand}" //커맨드 이름정의 및 바인딩
                    Content="Read" 
                    HorizontalAlignment="Left" 
                    VerticalAlignment="Top" 
                    Width="75" Height="41" 
                    Margin="447,256,0,0" 
                    RenderTransformOrigin="0.5,0.5"/>
        </Grid>
    </Window>

    view단은 위와 같이 소스와 화면을 첨부해 드립니다.

    그리고 ViewModel

    public class StudentViewModel : Notifier
        {
          
            private ObservableCollection<Student> foundStudents;
            public ObservableCollection<Student> FoundStudents
            {
                get { return foundStudents; }
                set
                {
                    foundStudents = value;
                    OnPropertyChenaged("FoundStudents");
                }
            }
    
            private Student selectedStudent;
            public Student SelectedStudent
            {
                get { return selectedStudent; }
                set
                {
                    selectedStudent = value;
                    OnPropertyChenaged("SelectedStudent");
                }
            }
    
            public StudentViewModel()
            {
            }
    
            StudentFactory factory = new StudentFactory();
            private ICommand readCommand;
            public ICommand ReadCommnad
            {
                get { return (this.readCommand) ?? (this.readCommand = new DelegateCommand(Read)); }
            }
    
            private void Read()
            {
                FoundStudents = factory.GetAllStudent();
            }
    
    
        }
    
        public class DelegateCommand : ICommand
        {
        private readonly Func<bool> canExecute;
        private readonly Action execute;
    
    	public DelegateCommand(Action exectue) : this(exectue, null)
    	{
    	}
    
    	public DelegateCommand(Action execute, Func<bool> canExecute)
    	{
    		this.execute = execute;
    		this.canExecute = canExecute;
    	}
    
    	public event EventHandler CanExecuteChanged;
    	public bool CanExecute(object parameter)
    	{
    		if (this.canExecute == null)
    		{
    		return true;
    		}
    		return this.canExecute();
    	}
    
    	public void Execute(object parameter)
    	{
    		this.execute();
    	}
    
    	public void RaiseCanExecuteChanged()
    	{
    		if (this.CanExecuteChanged != null)
    		{
    		this.CanExecuteChanged(this, EventArgs.Empty);
    		}
    	}

    처음에 Factory에 있는 데이터를 불러올 생성자를 만들고

    view단에서 사용할 모델명을 정의 줍니다.

    그리고 View단에서 xml을 연동시켜주는 clr을 꼭 숙지해주시고

    밑에 바인딩에 selected라는()winform에선 더블클릭으로 이벤트를 만들어주어 처리해준다)

    함수가 View단에서 바로 실행해주고 객체에 알아서 값을 찾아 넣어줍니다.

    이게 바인딩이라는 거죠.

    참 Mvvm패턴이란건 훌룡하고 좋은 것 같습니다.

    델리게이트는 그냥 복사 붙여 넣기 해주세요 

     

    위에 내용요약

    1.MVVM패턴을 만들 폴더를 나눈다 (View, ViewModel, Model)

    2. Model부분에 데이터베이스 연동 그리고 View, ViewModel에서 사용할 객체생성자 정의

    3. ViewModel에서는 View에서 사용할 객체 생성 및 정의 Command를 이용한 함수 정의

    4. View단에서 xml이 함수를 자동으로 구현해주어 바인딩을 해주므로 

    바인딩 할 부분과 객체 이름을 잘 생각하여 정의 

     

    여기 까지 WPF MVVM패턴을 알아 보았습니다.

    위에 내용을 

    복사 붙여 넣기 하여 

    구현해보신후 자신의 것으로 만들어 보시기 바랍니다.

    MVC패턴만 알때와 MVVM패턴을 같이 알때와는

    보는 시각의 넓이가 꾀차이나는 것 같습니다.

    잘 이해 하셨으면 좋겠네요

     

    (위에 내용은 MVVM패턴의 기본적인 개념을 

    아시는 분을 위한 내용이며 기본적인 개념은 다른 포스팅에서 다루고 있습니다)

    반응형

    댓글

Designed by Tistory.