[C#] 레지스트리를 활용한 Setting 내 CheckBox 설정 저장 기능

Jaemoon Lee·2022년 12월 9일
0

[C샾]

목록 보기
8/13
post-thumbnail

간단한 프로그램을 만들 때,
환경설정에 A모드와 B모드를 구분하고 싶을 때가 있다.

일단 내 기준으론 최근에 게시한 CheckSum을 검증한 뒤 RS232 메시지를 전송하는 기능이 이에 해당한다.

설비에 따라 CheckSum 기능을 굳이 사용하지 않아도 되는 상황이 있고,
혹은 무조건 CheckSum 기능을 사용하여 RS232 통신간 주고받는 메시지의 정합성을 판단해야할 필요가 있기 때문이다.

각설하고 일단 프로그램에 따로 Setting창이 존재하지 않아 어떻게 UI 위치를 조정하여 CheckSumUseMode 체크박스를 생성하였다.

참고로 CheckBox를 생성하는 가장 간단한 방법은
1. VisualStudio MainWindow.xaml(자신이 도구를 생성하고자하는 .xaml UI) 창에서
2. 화면 가장 우측 "도구 상자" 클릭

그럼 이렇게 VS가 다양하게 제공하는 컨트롤을 확인할 수 있다.

여기서 CheckBox를 클릭.

        </Grid>
        <CheckBox x:Name="cb_CheckSumMode" Content="CheckSum USE" HorizontalAlignment="Left" Height="17" VerticalAlignment="Top" Margin="73,114,0,0" Grid.Row="1"/>
    </Grid>

그럼 이렇게 작고 소중한 나만의 CheckBox가 생성된 것을 확인할 수 있을 것이다.

여기서 이제.. 위에 코드의 Content를 바꿔주면 위 사진의 CheckSum USE 텍스트를 변경할 수 있고,
기본 체크박스를 생성하면 아마 x:Name="cb_CheckSumMode" 이라는 구문은 만들어지지 않을텐데, 이것은 내가 해당 컨트롤에 임의로 부여한 일종의 고유식별자=이름표이다.

(https://learn.microsoft.com/ko-kr/dotnet/desktop/xaml-services/xname-directive)
→ XAML에서 x:Name의 의미 참고자료

이것을 부여한 이유는 해당 체크박스의 상태 변화에 따라 Mode를 사용하거나 미사용하는 것을 구분할 것이기 때문에...
이외 컨트롤도 코드 내에 그 값이나 상태를 어떠한 이유로든 사용할 것이라면 미리 정의해두는 것이 좋다.

아무튼,
먼저 CheckBox, 무슨무슨 Mode를 사용한다는 것은
사용하거나↔사용하지 않거나 로 구분할 수 있고,
이것은 프로그램 상에서 True거나 False거나,
즉, Boolean을 통해 구분할 수 있을 것이다.

그렇다면 CheckBox의 값이 True(1)면 CheckSumMode가 ON이고
False(0)면 Mode OFF일 것이라는 전제하에 프로그램을 구성하면 된다.

다행히, 당연히? 우리의 다양하고 강력한 라이브러리 클래스들을 제공하는 C#은 System.Windows.Controls.Primitives 내부에 ToggleButton이 선택된 상태인지 여부를 가져오거나 설정할 수 있도록 하는 bool 함수 IsCheckd를 지원하고 있다.

https://learn.microsoft.com/ko-kr/dotnet/api/system.windows.controls.primitives.togglebutton.ischecked?view=windowsdesktop-7.0
→ ToggleButton.IsChecked 속성 참고자료

체크박스가 체크되면 True, 해제되면 False를 반환하는 함수가 있으므로 이젠 무서울 것이 없다.

바로 코드에 테스트로 적용해보자면

//보드에 핀체크 명령을 날리는 버튼
        void GetPinData(object sender, RoutedEventArgs e)
        {
        	//보드가 연결되어 있으면...
            if (Store.getInstance().topSerial.IsOpen)
            {
            	//체크섬 모드가 체크되어 있으면...
                if (cb_CheckSumMode.IsChecked == true)
                {
                    string input1 = "<CONTACT1";
                    string checksum1 = GetHexChecksum(input1);
                    Store.getInstance().topSerial.Send("<CONTACT1^" + checksum1 + ">");

                    string input2 = "<PIN,ALL";
                    string checksum2 = GetHexChecksum(input2);
                    Store.getInstance().topSerial.Send("<PIN,ALL^" + checksum2 + ">");
                }
                //체크섬 모드가 해제되어 있으면...
                else
                {
                    //체크섬 미사용
                    Store.getInstance().topSerial.Send("<CONTACT1><PIN,ALL>");
                }
            }
            //보드가 연결되어있지 않으면...
            else
            {
                Store.getInstance().twLog.WriteLog("PINCHECK Fail : UpBoard Disconnected.");
            }
        }

위의 코드와 같이
//체크섬 모드가 체크, 해제되어 있으면... 을 bool함수의 리턴값을 기반한 조건문으로 프로그래밍화 할 수 있게 된다.


이어서, 체크박스 체크 여부에 따라 특정 Mode를 사용할지, 사용하지 않을지를 분기할 수 있게 되었는데,
이 함수는 당연하겠지만 프로그램 종료시에 메모리에서 즉각 제거되므로
내가 체크박스를 체크했더라도 프로그램을 껐다 다시 켜면 라이브러리에 지정된 Default 값으로 시작하게 된다.

당연히 사용자 입장에선 내가 특정 모드를 계속 사용하고자 하는데,
분명 방금 켜놓은 설정이 프로그램을 껐다 다시 켰다고 OFF돼있으면..
매번 다시 체크하는것도 상당히 귀찮아할 것이다. (겨우 이런것도 귀찮아할만큼 인간은 생각보다 나태하다.)

그렇기에 이것을 저장해두는 간단한 방법도 이전 게시물의 레지스트리 설정값 지정을 통해 해결할 수 있다.

//Settings.Designer.cs 파일 내 
//bool 함수 CheckSumModeUse의 Default Properties 설정

[global::System.Configuration.DefaultSettingValueAttribute("False")]
        public bool CheckSumModeUse
        {
            get
            {
                return ((bool)(this["CheckSumModeUse"]));
            }
            set
            {
                this["CheckSumModeUse"] = value;
            }
        }

우선 C#에서 지원하는... 함수의 기본 설정이라고 할 수 있는(여기선 함수값 get, get을 위해 지정.) Properties를 정의한다.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
→ Properties 참고자료

그리고 저장 시점에 대해...
한번 사용자가 CheckSumMode Use를 체크하고,
그 값을 프로그램 종료시 레지스트리에 자동 저장하도록 프로그램 종료 함수 내에 아래 코드들을 프로그래밍한다.

//프로그램 종료시 현재 체크박스 값을 저장하도록 조건문 지정.

            if (cb_CheckSumMode.IsChecked == true)
            {
                Properties.Settings.Default.CheckSumModeUse = true;
                reg.SetValue("CHECKSUMODEUSE", "1");
            }
            else
            {
                Properties.Settings.Default.CheckSumModeUse = true;
                reg.SetValue("CHECKSUMODEUSE", "0");
            }

이어서 사용자가 프로그램을 켤 때, 저장된 레지스트리 값을 Get하고,
해당 값에 따라 CheckSumMode를 True로 할지, False로 할지 구현한다.

//프로그램 시작 시 저장된 레지스트리 값을 가져옴.

            GetRegistryData();

            if (Properties.Settings.Default.CheckSumModeUse)
            {
                cb_CheckSumMode.IsChecked = true;
            }
            else
            {
                cb_CheckSumMode.IsChecked = false;
            }

여기서 난 bool 함수 true/false값을 1/0으로 레지스트리에 저장했는데,
이것을 ToString으로 변환한 뒤 CompareTo 함수를 이용해 1인지 0인지 비교해 CheckSumMonde의 Use 여부를 판단할 수 있도록 GetRegistryData(); 함수를 구현하였다.

// 위 코드의 GetRegistryData(); 함수.
// 해당 함수는 설정한 레지스트리 값을 불러오는 함수이다.

        public void GetRegistryData()
        {
            if (reg.GetValue("CHECKSUMODEUSE") != null)
            {
                if (reg.GetValue("CHECKSUMODEUSE").ToString().CompareTo("1") >= 0)
                {
                    Properties.Settings.Default.CheckSumModeUse = true;
                }
                else if (reg.GetValue("CHECKSUMODEUSE").ToString().CompareTo("0") >= 0)
                {
                    Properties.Settings.Default.CheckSumModeUse = false;
                }
            }
        }
profile
초보개발세발자

0개의 댓글