본문 바로가기

MAUI CollectionView 선택 상태 동기화가 안 될 때 발생하는 문제와 해결 전략 총정리

@veedeeo 2025. 12. 13. 16:13

MAUI로 앱을 개발하다 보면 CollectionView는 반드시 깊게 다뤄야 하는 핵심 UI 컴포넌트다. 단순 목록 표시를 넘어서 선택 상태 처리, 체크박스 구조, 외부 버튼과의 데이터 연동까지 모든 기능이 CollectionView를 중심으로 연결된다. 특히 많은 개발자들이 겪는 공통된 문제는 바로 선택 상태가 외부 UI와 정상적으로 동기화되지 않는 현상이다. 오늘 글에서는 이 부분을 완전히 이해할 수 있도록 내부 구조와 문제 원인, 해결 전략을 단계별로 정리한다.

 

CollectionView Selection Sync Diagram


1 선택 상태가 동기화되지 않는 이유

CollectionView가 화면에 보이는 방식은 단순해 보이지만 내부는 꽤 복잡하게 동작한다. 특히 선택 관련 기능에서는 다음 세 가지가 핵심이다.

1 체크박스와 IsSelected가 서로 다른 로직을 따르기 때문

CollectionView는 자체적으로 SelectionMode와 SelectedItem 내부 상태를 관리한다.
하지만 체크박스는 Binding Property만 바라본다.
따라서 다음처럼 불일치 상황이 발생할 수 있다.

  • 체크박스 체크를 했는데 SelectedItem은 안 바뀜
  • SelectedItem을 바꿨는데 체크박스 UI는 반영되지 않음
  • SelectionMode가 Single인데 체크박스를 여러 개 누를 수 있음
  • 외부에서 Model.IsSelected를 바꿔도 UI에 반영되지 않거나 깜빡임이 발생

즉 CollectionView SelectionMode와 사용자 정의 IsSelected 플래그는 서로 충돌할 가능성이 높다.

2 DataTemplate이 재활용되기 때문

MAUI의 CollectionView는 스크롤 성능을 위해 셀을 재활용한다.
그래서 다음 문제가 발생한다.

  • 스크롤 내렸다 올리면 체크박스 상태가 꼬인다
  • 이전 항목의 IsSelected 상태가 다음 셀에 잘못 반영된다
  • UI 반영은 됐지만 실제 데이터는 반영되지 않은 경우가 생긴다

재활용 구조를 이해하지 못하면 데이터를 변경해도 UI가 엉뚱하게 동작한다.

3 PropertyChanged가 제대로 작동하지 않는 경우

IsSelected가 UI에 반영되려면 Model이 INotifyPropertyChanged를 구현해야 한다.
하지만 구현 구조가 잘못되어 있으면 문제가 생긴다.

  • OnPropertyChanged가 호출되지 않는다
  • 동일한 값으로 변경했기 때문에 변경 이벤트가 발생하지 않는다
  • ObservableCollection은 항목 변경을 감지하지 않는다 List 변경만 감지한다

이 세 가지가 결합되면 UI를 눌렀는데 아무 반응이 없는 것처럼 보일 수 있다.


2 선택 상태가 외부 UI와 불일치할 때 나타나는 증상

이 문제는 단순히 체크박스 하나가 안 되는 정도가 아니라, 앱의 전체 흐름을 망가뜨린다. 실제 개발에서 매우 자주 겪는 증상은 다음과 같다.

1 체크박스 체크가 안 됨 또는 반대로 풀림

  • 체크박스를 눌러도 UI에 즉시 반영되지 않음
  • 다시 누르면 반대로 반응하거나 아예 무응답

2 외부 버튼에서 선택 항목을 읽으면 항상 빈 리스트가 나옴


Download Selected 버튼을 눌러도 선택된 항목이 없다고 뜬다.

3 선택을 바꿨을 때 UI가 반복 렌더링되면서 렉이 발생

  • 무한 루프처럼 SelectionChanged가 반복 호출
  • 체크박스 클릭마다 DataTemplate이 새로 렌더링됨
  • 앱이 잠깐 멈추거나 프레임 드랍

4 스크롤 시 UI 상태가 계속 바뀜

  • 위에선 체크가 되어 있었는데 아래 갔다 다시 오면 체크가 풀림
  • 또는 반대로 안 되어 있어야 하는데 체크되어 나타남

이 모든 문제는 SelectionMode과 사용자 정의 IsSelected가 충돌하면서 생긴다.


3 문제 원인을 구조적으로 파악하는 방법

결론적으로 CollectionView 선택 문제를 해결하려면 내부 흐름을 다음 순서로 분석하는 것이 가장 정확하다.

1 실제로 데이터가 변경되었는지 확인

체크박스를 누른 순간 Model.IsSelected가 변경되는가
변경되었다면 PropertyChanged가 호출되는가
변경되었는데도 UI가 안 바뀌는가

이 세 단계 중 한 곳에서 끊어지면 UI가 동작하지 않는다.

2 SelectionChanged 이벤트가 과도하게 호출되는지 확인

SelectionMode가 Single인데 체크박스를 통해 다중 선택을 시도하면
SelectionChanged가 반복 호출되며 UI가 재갱신된다.

이 경우 앱이 느려지거나 멈출 수 있다.

3 DataTemplate 재활용 흐름을 확인

스크롤하면서 DataTemplate이 재활용되는 경우
BindingContext가 바뀔 때 UI 초기값을 정확히 설정해주어야 한다.


4 가장 안정적인 해결 전략 정리

아래 5가지 전략은 MAUI CollectionView에서 선택 문제를 완전히 해결한 검증된 방식이다.


전략 1 SelectionMode를 None으로 설정할 것

만약 체크박스로만 선택을 관리한다면 반드시 아래처럼 설정해야 한다.

<CollectionView SelectionMode="None" />
 
 

SelectionMode=Single 또는 Multiple이면 내부 선택 로직과 충돌한다.


전략 2 Model에 INotifyPropertyChanged를 정확히 구현

IsSelected가 바뀌면 OnPropertyChanged가 호출되도록 한다.

 
private bool _isSelected;
public bool IsSelected
{
    get => _isSelected;
    set
    {
        if (_isSelected == value) return;
        _isSelected = value;
        OnPropertyChanged();
    }
}
 
 

값이 같으면 return해야 UI 무한 갱신을 막을 수 있다.


전략 3 체크박스 양방향 바인딩

XAML에서는 반드시 Mode=TwoWay를 명시한다.

<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}" />
 
 

TwoWay를 사용하지 않으면 UI에서 변경된 값이 Model에 전달되지 않는다.


전략 4 외부 UI와 따로 연결되는 로직은 ObservableCollection을 통해 접근

선택된 항목들을 가져오는 코드는 아래처럼 작성하는 것이 안정적이다.

var selectedItems = PlaylistItems.Where(x => x.IsSelected).ToList();
 
 

CollectionView.SelectedItems를 쓰지 않는다.


전략 5 UI 재활용 문제 방지를 위해 DataTemplate 내부 초기 상태를 명확히 설정

DataTemplate이 재활용될 때 체크박스가 기존 상태를 따라가야 한다.

 
<CheckBox
    IsChecked="{Binding IsSelected}"
    VerticalOptions="Center" />
 
 

이 구조가 가장 안전하다.


5 실제 앱 구조에서의 동작 예시

예를 들어
유튜브 재생목록
체크박스로 선택
선택된 항목만 다운로드
이런 UI가 있을 때 문제는 더 명확하게 나타난다.

선택된 항목 표시
외부 Download Selected 버튼 클릭
선택 개수 표시 갱신
선택된 항목만 다운로드

이 모든 기능은 IsSelected가 트리거로 동작한다.
따라서 선택 관리 구조는 앱 전체 안정성과 직결된다.


6 마무리 정리

오늘 글에서 다룬 선택 상태 동기화 문제는 MAUI CollectionView를 사용할 때 반드시 이해해야 하는 핵심 개념이다.
특히 체크박스 바인딩, SelectionMode 구조, UI 재활용, PropertyChanged 동작은 서로 긴밀히 연관되어 있다.

정리하면 아래 네 가지를 기억하면 된다.

  • SelectionMode는 None으로 설정
  • 체크박스는 IsSelected와 TwoWay 바인딩
  • Model은 반드시 INotifyPropertyChanged 구현
  • 외부 UI와 선택 상태는 ObservableCollection 기반으로 처리

이 네 가지 구조를 지키면 선택 상태 문제는 완전히 해결되며
CollectionView 기반 UI는 훨씬 안정적으로 동작한다.

veedeeo
@veedeeo :: .net MAUI·Netlify·SEO·웹 최적화 기술 블로그

.net MAUI·Netlify·SEO·웹 최적화 기술 블로그

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차