개발노트

13. [.NET MAUI] ObservableCollection로 ListView 바인딩하기 [MVVM] 본문

앱 개발/.NET MAUI

13. [.NET MAUI] ObservableCollection로 ListView 바인딩하기 [MVVM]

mroh1226 2022. 4. 14. 17:41
반응형

이번 시간에는 List<T>가 아닌 ObservableCollection<T> 라는 클래스를 사용하여 ListView에 연동 시켜본다.

(MVVM 패턴 유지)

 

- Model:       Quest.cs

- View:         Page21.xaml , Page21.xaml.cs (코드 비하인드)

- ViewModel: Page21_ViewModel.cs

 

https://docs.microsoft.com/ko-kr/dotnet/api/system.collections.objectmodel.observablecollection-1?view=net-6.0 

 

ObservableCollection<T> 클래스 (System.Collections.ObjectModel)

항목이 추가 또는 제거되거나 전체 목록이 새로 고쳐질 때 알림을 제공하는 동적 데이터 컬렉션을 나타냅니다.

docs.microsoft.com


1. Model이 될 class를 만들어 사용할 Entity를 작성한다.

(아래와 같이 Quest라는 클래스를 만들었다.)

 

Quest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppMaui.Models
{
    public class Quest
    {
        public Quest(string QName,int QLevel)
        {
            this.QuestName = QName;
            this.QuestLevel = QLevel;
        }

        public string QuestName { get; set; }
        public int QuestLevel { get; set; }

    }
}

 


2. Page21.xaml.cs (View)에 Page21_ViewModel.cs (ViewModel)을 바인딩한다.

(ViewModel에 Navigation이 있는 이유: 페이지 이동을 위해 INavigation을 파라로 받는 생성자를 사용하기 때문)

Page21_ViewModel.cs 
using AppMaui.ViewModels;
namespace AppMaui;

public partial class Page21 : ContentPage
{
	public Page21()
	{
		InitializeComponent();
		BindingContext = new Page21_ViewModel(Navigation);
	}
}

3. Page21_ViewModel.cs (ViewModel)에 ObservableCollection<T> 생성해주고, T에 Quest를 넣어 List처럼 사용한다.

추가적으로, 버튼 Command로 사용할 ICommand와 Quest(Model) Property가 변경됬음을 알릴 Notify 상속 및 OnPropertyChanged()를 작성해준다.

 

* btn_Click: 버튼을 누르면 어려운문제, 쉬운문제, 일반문제가 ListView에 추가 될 수 있도록 Add 메소드를 사용한다.

 

Page21_ViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AppMaui.Services;
using AppMaui.Models;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace AppMaui.ViewModels
{
    class Page21_ViewModel : Notify
    {
        public ObservableCollection<Quest> _Quests = new ObservableCollection<Quest>();
        public ICommand btn_Click { get; set; }

        public Page21_ViewModel()
        {

        }
        public Page21_ViewModel(INavigation navigation)
        {
            btn_Click = new Command(() =>
            {
                Quests.Add(new Quest("어려운 문제", 5));
                Quests.Add(new Quest("쉬운 문제", 2));
                Quests.Add(new Quest("일반 문제", 3));

            }, () =>
            {
                return true;
            });

            
        }

        public ObservableCollection<Quest> Quests
        {
            get => _Quests;
            set
            {
                if(_Quests != value)
                {
                    _Quests = value;
                    OnPropertyChanged("Quests");
                }
            }
        }
    }
}

 


4. Page21.xaml (View 마크업 소스)로 돌아와서 아래와 같이 Control을 작성하고 Property를 위에서 작성한 Quests와 그안의 QuestName, QuestLevel로 Binding 시켜준다.

 

* ItemsSource: ViewModel에 있는 ObservableCollection<Quest> Quests 바인딩한다.

* ItemTmplate 안의 DataTemplate에서 Quest.cs(Model)에 있는 QuestName, QuestLevel을 바인딩한다.

 

Page21.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="AppMaui.Page21"
             Title="Page21"
             BackgroundColor="White">

    <NavigationPage.TitleView>
        <Label Text="Page21"/>
    </NavigationPage.TitleView>

    <StackLayout>
        <Button Command="{Binding btn_Click}"/>
        <ListView x:Name="list_Quests" ItemsSource="{Binding Quests}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <ViewCell.View>
                            <Grid ColumnDefinitions="*,*">
                                <Label Grid.Column="0" Text="{Binding QuestName}"/>
                                <Label Grid.Column="1" Text="{Binding QuestLevel}"/>
                            </Grid>
                        </ViewCell.View>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

 


5. 빌드하고 버튼을 클릭해본다.

 

버튼이 클릭된 모습

 

끝!

반응형
Comments