개발노트

9. [.NET MAUI] IValueConverter로 string 형 값을 bool로 변환하기 본문

앱 개발/.NET MAUI

9. [.NET MAUI] IValueConverter로 string 형 값을 bool로 변환하기

mroh1226 2022. 3. 16. 13:43
반응형

IValueConverter 를 이용하여 특정 string 값이 되었을때 Bool형인 True를 반환하는 기능을 구현해본다.

 

- 정답일 때 Entry입력이 불가능하도록 IsEnabled Property의 값을 False 주고 오답일때 입력이 가능하도록 True를 주는 기능을 구현해보겠다.

 


 

1. Page10.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.Page10"
             Title="Page10"
             BackgroundColor="White">
    <NavigationPage.TitleView>
        <Label Text="Page10"/>
    </NavigationPage.TitleView>
    
    
    <StackLayout>
        <Grid RowDefinitions="*,*,*,*,*,*,*,*,*" ColumnDefinitions="*,*,*,*">
            <Label Grid.Row="0" Grid.RowSpan="6" Grid.Column="0" Grid.ColumnSpan="4" 
                   Text="IValueConverter를 이용한 문제풀기" FontSize="20" FontAttributes="Bold"/>

            <Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 
            	Text="사과나무에서 나는 과일은?" VerticalOptions="Center"/>
            <Entry Grid.Row="1" Grid.Column="2" HorizontalOptions="Fill"/>

            <Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" 
            	Text="바나나나무에서 나는 과일은?" VerticalOptions="Center"/>
            <Entry Grid.Row="2" Grid.Column="2" HorizontalOptions="Fill"/>

            <Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" 
            	Text="포도나무에서 나는 과일은?" VerticalOptions="Center"/>
            <Entry Grid.Row="3" Grid.Column="2" HorizontalOptions="Fill"/>

            <Button Grid.Row="8" Grid.Column="0" Grid.ColumnSpan="4" Text="BackToMain" 
            	Command="{Binding cmd_BackToMain}" />
            
        </Grid>
        
    </StackLayout>
</ContentPage>

2. ViewModel에 Xaml에 있는 Entry의 Text를 바인딩하기 위해 아래와 같이 3개의 Answer를 선언해준다.

*문제 정보를 갖는 객체를 만들어서 Model쪽으로 처리하는게 좋을 것 같다. (질문, 답지, 해설, 점수 등의 변수를 갖는..?)

 

나중에 생각하기로 하고, 우선 ViewModel에 바로 구현해준다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AppMaui.Services;
using System.Windows.Input;

namespace AppMaui.ViewModels
{
    class Page10_ViewModel : Notify
    {
        public INavigation nv_BackToMain { get; set; }
        public ICommand cmd_BackToMain { get; set; }
        public string _Answer1 { get; set; }
        public string _Answer2 { get; set; }
        public string _Answer3 { get; set; }

        public Page10_ViewModel()
        {

        } 

        public Page10_ViewModel(INavigation navigation)
        {
            nv_BackToMain = navigation;

            cmd_BackToMain = new Command( () =>
            {
                nv_BackToMain.PopToRootAsync(); //처음 Navigation Root로 돌아가기
            }, () =>
            {
                return true;
            });

        }

        public string Answer1
        {
            get=> _Answer1;
            set
            {
                if(_Answer1 != value)
                {
                    _Answer1 = value;
                    OnPropertyChanged("Answer1");
                }
            }
        }

        public string Answer2
        {
            get=> _Answer2;
            set
            {
                if(_Answer2 != value)
                {
                    _Answer2 = value;
                    OnPropertyChanged("Answer2");
                }
            }
        }

        public string Answer3
        {
            get=> _Answer3;
            set
            {
                if(_Answer3 != value)
                {
                    _Answer3 = value;
                    OnPropertyChanged("Answer3");
                }
            }
        }


    }
}

3. IValueConverter를 상속받을 새로운 클래스를 Services 디렉토리에 생성해준다.
Class명은 stringToBoolConverter.cs 로 만들어 주었고 아래와같이 소스를 작성한다.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppMaui.Services
{
    class stringToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type typeTarget, object parameter, CultureInfo culture)
        {
            if (value == null) return true;

            if(parameter != null)
            {
                switch (parameter.ToString())
                {
                    case "1": if (value.ToString() == "apple") return false; break;
                    case "2": if (value.ToString() == "banana") return false; break;
                    case "3": if (value.ToString() == "grape") return false; break;
                    default: return true; break;
                }
            }
            return true;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (bool)value ? 1 : 0;
        }
    }
}

Convert 메소드를 통해 4가지 매개변수를 이용할 수 있다.

ConvertBack은 Mode = TwoWay일 때 사용된다.
(삼항 연산자: ? 앞의 조건이 true일때 왼쪽 값, false일때 오른쪽 값 리턴)

 

 

- IValueConverter 참고자료

https://docs.microsoft.com/ko-kr/dotnet/api/system.windows.data.ivalueconverter?view=windowsdesktop-6.0#methods 

 

IValueConverter 인터페이스 (System.Windows.Data)

바인딩에 사용자 지정 논리를 적용할 방법을 제공합니다.

docs.microsoft.com


4. 마크업 소스로 돌아가서 바인딩해준다.

<?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"
             xmlns:service="clr-namespace:AppMaui.Services" 
             x:Class="AppMaui.Page10"
             Title="Page10"
             BackgroundColor="White">
    <NavigationPage.TitleView>
        <Label Text="Page10"/>
    </NavigationPage.TitleView>

    <ContentPage.Resources>
        <service:stringToBoolConverter x:Key="stringTobool"/>
    </ContentPage.Resources>
    
    
    <StackLayout>
        <Grid RowDefinitions="*,*,*,*,*,*,*,*,*" ColumnDefinitions="*,*,*,*">
            <Label Grid.Row="0" Grid.RowSpan="6" Grid.Column="0" Grid.ColumnSpan="4" 
                   Text="IValueConverter를 이용한 문제풀기" FontSize="20" FontAttributes="Bold"/>

            <Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 
            	Text="사과나무에서 나는 과일은?" VerticalOptions="Center"/>
            <Entry x:Name="Entry1" Grid.Row="1" Grid.Column="2" HorizontalOptions="Fill"
                   Text="{Binding Answer1}"
                   IsEnabled="{Binding Source={x:Reference Entry1},Path=Text, 
                   ConverterParameter=1,Converter={x:StaticResource stringTobool}}"/>

            <Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" 
            	Text="바나나나무에서 나는 과일은?" VerticalOptions="Center"/>
            <Entry x:Name="Entry2" Grid.Row="2" Grid.Column="2" HorizontalOptions="Fill"
                   Text="{Binding Answer2}"
                   IsEnabled="{Binding Source={x:Reference Entry2},Path=Text, 
                   ConverterParameter=2,Converter={x:StaticResource stringTobool}}"/>

            <Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" 
            	Text="포도나무에서 나는 과일은?" VerticalOptions="Center"/>
            <Entry x:Name="Entry3" Grid.Row="3" Grid.Column="2" HorizontalOptions="Fill"
                   Text="{Binding Answer3}"
                   IsEnabled="{Binding Source={Reference Entry3},Path=Text, 
                   ConverterParameter=3, Converter={x:StaticResource stringTobool}}"/>

            <Button Grid.Row="8" Grid.Column="0" Grid.ColumnSpan="4" Text="BackToMain" 
            	Command="{Binding cmd_BackToMain}" />
            
        </Grid>
        
    </StackLayout>
</ContentPage>

 

4-1) stringToBoolConverter를 사용하기 위해서 xmlns(네임스페이스)에 Services를 선언해준다.
4-2) ContentPage.Resources 를 통해 stringToBoolConverter를 등록해주고 x:key로 stringTobool 라고 구분해준다.

4-3) Entry에 x:Name을 이용하여 이름을 정해주고 Text에 각각의 string형인 Answer를 바인딩해준다.

4-4) IsEnabled에 x:Reference 나 Reference를 통해 x:Name으로 이름을 갖고 있는 컴포넌트를 Source 바인딩하고, Path로 Entry가 가지고있는 Property 중 Text를 연결해준다.
(IsEnabled는 Entry에 문자를 입력할 수 있게 해주는 Property로, true, false로 조정할 수 있음)

4-5) ConvertParameter에 Convert 메소드 안에서 구현했던 case 값이 구분되도록 parameter 값을 각각 넣어준다.

4-6) 마지막으로 x:StaticResource를 통해 Resources에 등록했던 stringTobool로 Converter를 설정해준다. 

 


5. 빌드해본다.

 

빌드된 모습

정답을 맞추면 Entry = false가 되어 수정할 수 없게되고, 오답이면 IsEnable = true 이기 때문에 계속 수정가능 하다.

 

끝!

반응형
Comments