티스토리 뷰

반응형

내급여 UWP 앱 개발

Part1

Part2

Part3

Part4

 

 

**. 설정의 급여 기본 정보

 

급여 정보 모델을 수정 했습니다.

 

시작시간, 종료시간, 시급 프로퍼티는 기본 값으로 입력된 후 저장된 데이터를 불러와서 변경을 시켜주게 되는데, 변경된 데이터가 화면에 갱신이 되도록 하려면 아래와 같이 수정해 주어야 합니다.

 

값과 휴일 유무는 개발을 진행하다가 추가된 프로퍼티들입니다.  

 

1. PayInformation

 


    ///     급여 정보
    /// </summary>
    public class PayInformation : Observable
    {
        private DateTime _endTime;
        private DateTime _startTime;
        private int _timePay;


        /// <summary>
        ///     아이디
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        ///     값
        /// </summary>
        public double Value { get; set; }

        /// <summary>
        ///     휴일 유무
        /// </summary>
        public bool IsHoliday { get; set; }

        /// <summary>
        ///     시작시간
        /// </summary>
        public DateTime StartTime
        {
            get => _startTime;
            set => Set(ref _startTime, value);
        }

        /// <summary>
        ///     종료시간
        /// </summary>
        public DateTime EndTime
        {
            get => _endTime;
            set => Set(ref _endTime, value);
        }

        /// <summary>
        ///     시급
        /// </summary>
        public int TimePay
        {
            get => _timePay;
            set => Set(ref _timePay, value);
        }

    }

 

 

2. SettingViewModel

 

설정 뷰 모델 생성자 수정 했습니다.

생각을 해보니 평일과 휴일를 각각 입력해야 하더군요. 그래서 생성자에서 각 단계별로 4개씩 총 8개를 넣어 놓습니다.

 

        /// <summary>
        ///     기본 생성자
        /// </summary>
        public SettingsViewModel()
        {
            SwitchThemeCommand = new RelayCommand(async () => { await ThemeSelectorService.SwitchThemeAsync(); });

            LoadedCommand = new RelayCommand(OnLoaded);
            UnloadedCommand = new RelayCommand(OnUnloaded);

            PayInformations = new List<PayInformation>
            {
                new PayInformation
                {
                    Id = "1.0",
                    Value = 1.0,
                    StartTime = DateTime.Parse("08:00"),
                    EndTime = DateTime.Parse("18:00"),
                    TimePay = 10000
                },
                new PayInformation
                {
                    Id = "1.5 Part1",
                    Value = 1.5,
                    StartTime = DateTime.Parse("08:00"),
                    EndTime = DateTime.Parse("18:00"),
                    TimePay = 10000
                },
                new PayInformation
                {
                    Id = "2.0",
                    Value = 2.0,
                    StartTime = DateTime.Parse("08:00"),
                    EndTime = DateTime.Parse("18:00"),
                    TimePay = 10000
                },
                new PayInformation
                {
                    Id = "1.5 Part2",
                    Value = 1.5,
                    StartTime = DateTime.Parse("08:00"),
                    EndTime = DateTime.Parse("18:00"),
                    TimePay = 10000
                },
                new PayInformation
                {
                    Id = "1.5 Holiday",
                    Value = 1.5,
                    IsHoliday = true,
                    StartTime = DateTime.Parse("08:00"),
                    EndTime = DateTime.Parse("18:00"),
                    TimePay = 10000
                },
                new PayInformation
                {
                    Id = "2.0 Holiday1",
                    Value = 2.0,
                    IsHoliday = true,
                    StartTime = DateTime.Parse("08:00"),
                    EndTime = DateTime.Parse("18:00"),
                    TimePay = 10000
                },
                new PayInformation
                {
                    Id = "2.5 Holiday",
                    Value = 2.5,
                    IsHoliday = true,
                    StartTime = DateTime.Parse("08:00"),
                    EndTime = DateTime.Parse("18:00"),
                    TimePay = 10000
                },
                new PayInformation
                {
                    Id = "2.0 Holiday2",
                    Value = 2.0,
                    IsHoliday = true,
                    StartTime = DateTime.Parse("08:00"),
                    EndTime = DateTime.Parse("18:00"),
                    TimePay = 10000
                }

            };
        }

 

 

3. 저장하기와 불러오기

 

데이터 저장하기와 불러오기는 ApplicationData Class 를 이용합니다.

 

저장을 먼저 해보죠..

ApplicationData.Current.LocalSettings는 앱 데이터를 저장할 수 있는 고유 공간입니다. 그리고 뒤에 SaveAsync는 확장 메소드로 F12(정의로 이동)를 눌러보시면 어떻게 동작하는지 아실 수 있을 것입니다.

 

OnLoaded가 실행될 때 저장되어있던 데이터를 ReadAsync라는 확장 메소드를 이용해 불러와서 시작시간 종료시간 시급을 넣어 줍니다. 물론 저장된 내용이 없으면, 그냥 기존데이터를 보여주겠죠?

 

        private async void OnUnloaded()
        {
            //종료되기 전에 저장
            foreach (var pay in PayInformations)
                await ApplicationData.Current.LocalSettings.SaveAsync(pay.Id, pay);
        }

        private async void OnLoaded()
        {
            //저장된 데이터 불러오기
            foreach (var pay in PayInformations)
            {
                var savedPay = await ApplicationData.Current.LocalSettings.ReadAsync<PayInformation>(pay.Id);
                if (savedPay == null) continue;
                pay.StartTime = savedPay.StartTime;
                pay.EndTime = savedPay.EndTime;
                pay.TimePay = savedPay.TimePay;
            }
        }

 

 

4. SettingPage.xam

 

그리드에 데이터가 8줄이 들어가기 때문에 강제로 컨트롤의 높이를 200으로 한정했으며, RadDataGrid를 감싸고 있던  StackPanel을 제거 했습니다. 또한, 새로 추가한 프로퍼티를 보여줄 컬럼을 추가합니다.

 

            <grid:RadDataGrid Grid.Row="1" Margin="0,16,0,0" ColumnDataOperationsMode="Flyout" UserEditMode="Inline"
                              UserGroupMode="Disabled" AutoGenerateColumns="False"
                              ItemsSource="{Binding PayInformations}" HorizontalAlignment="Left"
                              Height="200">
                <grid:RadDataGrid.Columns>
                    <grid:DataGridTextColumn Header="Id" PropertyName="Id" CanUserEdit="False" SizeMode="Auto"/>
                    <grid:DataGridBooleanColumn Header="Holiday" PropertyName="IsHoliday" SizeMode="Fixed" Width="80" />
                    <grid:DataGridTimeColumn PropertyName="StartTime" Header="Start" CellContentFormat="{}{0:t}"
                                             SizeMode="Auto" />
                    <grid:DataGridTimeColumn PropertyName="EndTime" Header="End" CellContentFormat="{}{0:t}"
                                             SizeMode="Auto" />
                    <grid:DataGridNumericalColumn Header="Hour Pay" PropertyName="TimePay" SizeMode="Auto" CellContentFormat="{}{0:n0}"/>

                </grid:RadDataGrid.Columns>
            </grid:RadDataGrid>

 

 

 

이정도 수정을 한 후 실행 후 수정을 원하는 컬럼을 선택하면 아래와 같이 나옵니다.

 

 

저장된 데이터는 어디에 들어가 있을까요?

 

제 컴퓨터에서는 아래 경로에 settings.dat 파일이 존재합니다. 

 

C:\Users\MunChan Park\AppData\Local\Packages\CA3D44E9-05D5-4474-AB5D-89CB15FA4C9E_v0qv1p8057pc0\Settings

 

폴더명이 좀 어렵기 때문에 쉽게 찾을 수는 없습니다.

 

 

5. 기준월 추가

 

GridViewModel

 

앱이 시작하면 지난달을 기준 월로 지정하도록 만들었으며, 문자열 형태입니다.

 

        /// <summary>

        ///     기준 월
        /// </summary>
        public string BaseMonth
        {
            get => _baseMonth;
            set => Set(ref _baseMonth, value);
        }

        private string _baseMonth; 

 

지난달은 입력은 AddMonths를 이용하면 됩니다.

 

        private void Init()
        {
            LoadedCommand = new RelayCommand(OnLoaded);
            UnloadedCommand = new RelayCommand(OnUnloaded);

            BaseMonth = DateTime.Now.AddMonths(-1).ToString("yyyy-MM");

            PropertyChanged += GridViewModel_PropertyChanged;

            CreateMonthData();
        }

 

GridPage.xaml

 

기준 월을 출력하는 것은 화면 오른쪽 상단에 출력하며, 기준월을 변경할 경우를 대비해서 TwoWay를 이용합니다.

 

        <StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center">
            <TextBlock Text="Month" VerticalAlignment="Center"/>
            <TextBox Text="{Binding BaseMonth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </StackPanel>

 

 

6. 1일부터 월말까지 데이터 자동 생성

 

기준월이 정해지면 해당 월의 1일부터 월말 까지 데이터를 자동으로 생성해서 화면에 출력합니다.

 

우선 1일부터 31일까지를 배열로 만들어 놓고, GetDate 함수를 이용해서 진짜 존재하는 일자인지 확인해서 반환하고 결과가 null이면 포함하지 않도록 하구요 무슨 요일인지도 반환하도록 해서 주말이면, IsHoliday를 설정하도록 합니다.

 

        private readonly int[] _monthData =
        {
            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
            30, 31
        };

       

        private void CreateMonthData()
        {
            if (string.IsNullOrEmpty(BaseMonth)) return;
            //31개의 데이터를 입력
            Works = (from num in _monthData
                let dayNullable = GetDate($"{BaseMonth}-{num}")
                where dayNullable != null
                let day = (DateTime) dayNullable
                let week = day.DayOfWeek
                let holiday = week == DayOfWeek.Saturday || week == DayOfWeek.Sunday
                select new WorkItem
                {
                    Id = num,
                    WorkDay = day,
                    IsHoliday = holiday,
                    StartWork = holiday
                        ? DateTime.Parse($"{day:yyyy-MM-dd} 00:00")
                        : DateTime.Parse($"{day:yyyy-MM-dd} 08:00"),
                    EndWork = holiday
                        ? DateTime.Parse($"{day:yyyy-MM-dd} 00:00")
                        : DateTime.Parse($"{day:yyyy-MM-dd} 18:00")
                }).ToList();
        }

 

        /// <summary>
        ///     문자열 날짜를 데이트타임 형으로 변환
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private DateTime? GetDate(string date)
        {
            DateTime returnDate;
            if (DateTime.TryParse(date, out returnDate))
                return returnDate;
            return null;
        }

 

 

 

 

7. 기타

 

작업을 하다보니, 모델도 수정하고, 그리드도 수정을 해서.. 오늘까지의 소스는 여기에 올리도록 하겠습니다.

 

MyPay_part4.zip

 

 

8. 주의

 

                    <tg:DataGridDateColumn PropertyName="WorkDay" Header="Work Day" CellContentFormat="{}{0:d}"
                                           SizeMode="Fixed" />

 

RadDataGrid의 첫번째 컬럼을 CanUserEdit="False"로 변경하면,

 

System.NullReferenceException: Object reference not set to an instance of an object.
   at Telerik.UI.Xaml.Controls.Grid.XamlGridEditCellGenerator.GenerateContainerForItem(CellGenerationContext info, Object containerType)
   at Telerik.UI.Xaml.Controls.Grid.CellEditorModelGenerator.GenerateContainerForItem(CellGenerationContext context, Object containerType)
   at Telerik.UI.Xaml.Controls.Grid.ItemModelGenerator`2.GenerateContainer(K context)
   at Telerik.UI.Xaml.Controls.Grid.CellsController`1.GetCell

 

수정하려고 했을 때 에러가 발생합니다. 사실 이 에러가 발생해서 맨붕이 와서..다른걸로 변경하려다가....흐흐흐

반응형

'UWP & Windows App > Beginner' 카테고리의 다른 글

내급여 UWP 앱 개발 part6  (0) 2017.09.25
내급여 UWP 앱 개발 part5  (0) 2017.09.18
내급여 UWP 앱 개발 part3  (0) 2017.08.26
내급여 UWP 앱 개발 part2  (4) 2017.08.24
내급여 UWP 앱 개발 part1  (0) 2017.08.22
댓글