본문 바로가기

MAUI CollectionView에서 체크박스 선택 상태가 반영되지 않을 때 반드시 확인해야 하는 구조적 문제와 해결 전략

@veedeeo 2025. 12. 11. 11:55

MAUI 기반 앱에서 CollectionView를 사용하여 목록을 구현할 때 가장 자주 발생하는 오류 중 하나가 바로 체크박스의 상태가 데이터 모델과 정확하게 동기화되지 않는 문제입니다. 화면에서는 체크박스가 눌린 것처럼 보이지만 내부 ViewModel의 IsSelected 값은 변하지 않거나 반대로 IsSelected 속성은 변경되었는데 UI에서는 체크 상태가 반영되지 않는 경우가 발생합니다. 특히 안드로이드 환경에서는 이벤트 처리 우선순위, 레이아웃 터치 충돌, SelectionMode 내부 로직과의 조합 때문에 더욱 복잡한 형태의 버그가 나타나기 쉽습니다. 이 글에서는 이러한 오류가 발생하는 원리를 구조적으로 분석하고, 실제 개발 과정에서 반드시 점검해야 하는 세부 요소들을 심층적으로 정리했습니다. 단순한 체크박스 오류 해결을 넘어, MAUI CollectionView의 동작 방식 자체를 이해하는 데 도움이 되도록 설명을 확장했습니다.

 

MAUI CollectionView Debugging


1. SelectionMode와 CheckBox 바인딩의 구조적 충돌 이해

CollectionView의 SelectionMode 속성은 내부적으로 항목의 선택 상태를 제어하는 메커니즘을 포함하고 있습니다. SelectionMode가 Single 또는 Multiple로 설정된 상황에서는 사용자가 특정 항목을 터치했을 때 CollectionView가 자동으로 IsSelected 값을 업데이트하려고 시도합니다. 그런데 ItemTemplate 안에 배치된 CheckBox가 동일한 속성을 제어하려고 하면 UI와 데이터 모델 사이에 제어권 충돌이 발생합니다. 이 충돌은 단순한 우선순위 문제가 아니라 내부 SelectionChanged 이벤트 처리 메커니즘과 CheckBox의 CheckedChanged 이벤트가 서로 경쟁하는 구조적인 문제입니다.

예를 들어 CheckBox가 체크되는 순간 IsSelected 속성이 true로 바뀌지만, CollectionView는 자체 SelectionMode 로직을 실행하면서 다시 값을 원래대로 되돌리거나 갱신하지 않은 상태로 유지하려고 할 수 있습니다. 이 현상은 특히 안드로이드에서 빈번하게 나타나며, 대부분의 체크 오류가 여기서 비롯됩니다.

해결 방법

SelectionMode를 None으로 설정해 CollectionView 내부의 선택 로직을 완전히 비활성화하고, 선택 상태는 전적으로 ViewModel이 관리하도록 구성합니다. 이렇게 하면 CheckBox와 IsSelected 바인딩이 단일 흐름으로 정리되어 충돌 위험이 사라집니다.

<CollectionView SelectionMode="None">
 

2. ItemTemplate 내부에 과도하게 복잡한 레이아웃 배치

MAUI는 플랫폼별로 터치 이벤트 전달 방식이 미묘하게 다릅니다. Grid, Border, HorizontalStackLayout 등이 중첩된 경우 최상위 컨테이너가 터치 이벤트를 가로채서 하위 요소인 CheckBox까지 이벤트가 정상적으로 전달되지 못하는 상황이 발생할 수 있습니다. 특히 GestureRecognizer를 장착한 레이아웃이 포함되어 있다면 CheckBox는 터치 신호를 받지 못하고 체크 상태가 UI에서 반응하지 않게 됩니다.

이 문제는 개발자가 보기에는 레이아웃이 단순해 보여도, 실제로는 특정 요소가 InputTransparent 설정을 잘못 가지고 있거나 터치 처리가 상위 레이어에서 소비되는 구조 때문입니다.

해결 방법

  • ItemTemplate의 최상위 Grid에 InputTransparent 속성을 False로 명시
  • 불필요한 TapGestureRecognizer 제거

Padding이 과도해 CheckBox의 클릭 범위를 침범하지 않는지 확인

<Grid InputTransparent="False">

3. ViewModel에서 INotifyPropertyChanged 구현 누락 또는 잘못된 Notify 호출

체크 상태가 UI에 반영되지 않거나 스크롤할 때 초기화되는 문제의 근본 원인은 많은 경우 ViewModel에서 PropertyChanged 이벤트가 제대로 호출되지 않기 때문입니다. MAUI CollectionView는 데이터 바인딩 기반으로 동작하기 때문에 속성 변경 알림이 없다면 UI 갱신이 일어나지 않습니다.

다음과 같은 단순한 실수 하나로 전체 체크 구조가 무너질 수 있습니다.

  • 동일한 값이 들어와도 PropertyChanged가 호출되지 않음
  • OnPropertyChanged 메서드 구현 누락
  • 필드 값 업데이트 전에 Notify 호출
  • SetProperty 패턴 누락

올바른 구현 예시

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

여기서 중요한 점은 IsSelected의 변경이 ViewModel의 단일 진실 소스(Single Source of Truth) 역할을 하도록 유지하는 것입니다.


4. ObservableCollection 대신 List를 사용한 경우 발생하는 문제

CollectionView는 List의 변경을 자동으로 감지하지 않으며 UI를 다시 그릴 시 내부적으로 ItemTemplate을 재사용하기 때문에 체크 상태가 일정하지 않게 나타날 수 있습니다. 특히 아래와 같은 증상이 나타납니다.

  • 스크롤하면 체크가 풀리는 현상
  • 새 항목 추가 후 UI에 반영되지 않는 문제
  • 원소 순서가 바뀔 때 체크 상태가 섞이는 문제

해결 방법

항상 ObservableCollection을 사용하고, ViewModel에서만 데이터를 조작하도록 유지합니다.


5. Template 재활용(Recycling)으로 인한 상태 초기화 문제

MAUI CollectionView는 성능 최적화 목적을 위해 화면에서 사라진 항목의 템플릿을 재사용합니다. 이 때문에 UI 내부 상태를 저장하는 방식은 모두 문제를 일으킵니다. 예를 들어 CheckBox의 초기값을 XAML에서 직접 하드코딩하거나 로컬 변수로 상태를 관리하면 템플릿 재사용 시 이전 항목의 상태가 남아 있게 됩니다.

해결 방법

  • CheckBox의 상태는 항상 바인딩으로만 결정
  • 초기 상태는 XAML에서 강제로 설정하지 말고 ViewModel에서 관리
  • 스크롤 시 재활용되는 구조임을 고려해 데이터 기반 구조 유지

MAUI CollectionView Checkbox Errors Diagram


종합 정리

MAUI CollectionView에서 체크박스 선택 상태가 정상적으로 반영되지 않는 문제는 대부분 구조적 이해 부족에서 비롯됩니다. SelectionMode, 레이아웃 터치 충돌, PropertyChanged 누락, ObservableCollection 부재, 템플릿 재활용 규칙 등은 개별적으로 작동하는 것이 아니라 서로 영향을 주며 오류를 가중시킵니다. 이 글에서 정리한 다섯 가지 항목을 기반으로 구조를 하나씩 점검하면 대부분의 선택 오류는 빠르게 해결되며, 앱의 동작 안정성과 사용자 경험 품질도 크게 향상됩니다.

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

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

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

목차