Example #1
0
        /// <summary>
        /// 把人员从文件夹中导入到Face API中。
        /// </summary>
        /// <returns></returns>
        private async Task ImportFromFolderAndFilesAsync()
        {
            this.commandBar.IsOpen = false;

            this.progressControl.IsActive = true;

            List <string> errors = new List <string>();

            try
            {
                foreach (var folder in await autoTrainFolder.GetFoldersAsync())
                {
                    string personName = Util.CapitalizeString(folder.Name.Trim());
                    if (string.IsNullOrEmpty(personName))
                    {
                        continue;
                    }

                    if (!this.PersonsInCurrentGroup.Any(p => p.Name == personName))
                    {
                        await FaceServiceHelper.CreatePersonAsync(this.CurrentPersonGroup.PersonGroupId, personName);
                    }

                    Person newPerson = (await FaceServiceHelper.GetPersonsAsync(this.CurrentPersonGroup.PersonGroupId)).First(p => p.Name == personName);

                    foreach (var photoFile in await folder.GetFilesAsync())
                    {
                        try
                        {
                            await FaceServiceHelper.AddPersonFaceAsync(
                                this.CurrentPersonGroup.PersonGroupId,
                                newPerson.PersonId,
                                imageStream : await photoFile.OpenStreamForReadAsync(),
                                userData : photoFile.Path,
                                targetFace : null);

                            // Force a delay to reduce the chance of hitting API call rate limits
                            await Task.Delay(250);
                        }
                        catch (Exception)
                        {
                            errors.Add(photoFile.Path);
                        }
                    }

                    this.PersonsInCurrentGroup.Add(newPerson);
                }
            }
            catch (Exception ex)
            {
                await Util.GenericApiCallExceptionHandler(ex, AppResourcesHelper.GetString("PersonGroupDetailsPage_ErrorImportPerson"));
            }

            if (errors.Any())
            {
                await new MessageDialog(string.Join("\n", errors), AppResourcesHelper.GetString("PersonGroupDetailsPage_MsgImportFailure")).ShowAsync();
            }

            this.progressControl.IsActive = false;
        }
        public MainDesignViewModel()
        {
            Menu = new VisualMenu
            {
                Groups = new ObservableCollection <VisualGenericGroup>
                {
                    new VisualGenericGroup
                    {
                        Title = AppResourcesHelper.GetString("LBL_NEWS")
                    },
                    new VisualGenericGroup
                    {
                        Title = AppResourcesHelper.GetString("LBL_BUREAU")
                    },
                    new VisualGenericGroup
                    {
                        Title = AppResourcesHelper.GetString("LBL_PROJECTS")
                    },
                    new VisualGenericGroup
                    {
                        Title = AppResourcesHelper.GetString("LBL_CONFERENCES")
                    },
                    new VisualGenericGroup
                    {
                        Title = AppResourcesHelper.GetString("LBL_SALONS")
                    }
                }
            };

            SelectedItem = Menu.Groups[0].Items[0];
        }
Example #3
0
        private async void OnStartTrainingClicked(object sender, RoutedEventArgs e)
        {
            this.progressControl.IsActive = true;

            TrainingStatus trainingStatus = null;

            try
            {
                await FaceServiceHelper.TrainPersonGroupAsync(this.CurrentPersonGroup.PersonGroupId);

                while (true)
                {
                    trainingStatus = await FaceServiceHelper.GetPersonGroupTrainingStatusAsync(this.CurrentPersonGroup.PersonGroupId);

                    if (trainingStatus.Status != Status.Running)
                    {
                        break;
                    }
                    await Task.Delay(1000);
                }
            }
            catch (Exception ex)
            {
                await Util.GenericApiCallExceptionHandler(ex, AppResourcesHelper.GetString("PersonGroupDetailsPage_ErrorRequestTrain"));
            }

            this.progressControl.IsActive = false;

            if (trainingStatus.Status != Status.Succeeded)
            {
                await new MessageDialog(AppResourcesHelper.GetString("PersonGroupDetailsPage_ErrorTrainFailure")).ShowAsync();
            }
        }
Example #4
0
 private void visionToggleChanged(object sender, RoutedEventArgs e)
 {
     if (!this.visionToggle.IsOn)
     {
         this.visionAPICaptionTextBlock.Text = AppResourcesHelper.GetString("RealtimeDriverMonitoring_AnalyzeActivities");
         this.objectDistraction.Visibility   = Visibility.Collapsed;
     }
 }
Example #5
0
 private async void OnResetSettingsClick(object sender, RoutedEventArgs e)
 {
     await Util.ConfirmActionAndExecute(AppResourcesHelper.GetString("SettingsPage_ResetTip"),
                                        async() =>
     {
         await Task.Run(() => SettingsHelper.Instance.RestoreAllSettings());
         await new MessageDialog(AppResourcesHelper.GetString("SettingsPage_ResetFinish")).ShowAsync();
     });
 }
Example #6
0
        private async void OnConfirmImportButtonClicked(object sender, RoutedEventArgs e)
        {
            this.addPeopleInBatchesFlyout.Hide();
            this.commandBar.IsOpen = false;

            this.progressControl.IsActive = true;

            try
            {
                string[] names = this.importNamesTextBox.Text.Split('\n');
                foreach (var name in names)
                {
                    string personName = Util.CapitalizeString(name.Trim());
                    if (string.IsNullOrEmpty(personName) || this.PersonsInCurrentGroup.Any(p => p.Name == personName))
                    {
                        continue;
                    }

                    await FaceServiceHelper.CreatePersonAsync(this.CurrentPersonGroup.PersonGroupId, personName);

                    Person newPerson = (await FaceServiceHelper.GetPersonsAsync(this.CurrentPersonGroup.PersonGroupId)).First(p => p.Name == personName);

                    IEnumerable <string> faceUrls = await BingSearchHelper.GetImageSearchResults(string.Format("{0} {1} {2}", this.importImageSearchKeywordPrefix.Text, name, this.importImageSearchKeywordSufix.Text), count : 2);

                    foreach (var url in faceUrls)
                    {
                        try
                        {
                            ImageAnalyzer imageWithFace = new ImageAnalyzer(url);

                            await imageWithFace.DetectFacesAsync();

                            if (imageWithFace.DetectedFaces.Count() == 1)
                            {
                                await FaceServiceHelper.AddPersonFaceAsync(this.CurrentPersonGroup.PersonGroupId, newPerson.PersonId, imageWithFace.ImageUrl, imageWithFace.ImageUrl, imageWithFace.DetectedFaces.First().FaceRectangle);
                            }
                        }
                        catch (Exception)
                        {
                            // Ignore errors with any particular images and continue
                        }

                        // Force a delay to reduce the chance of hitting API call rate limits
                        await Task.Delay(250);
                    }

                    this.PersonsInCurrentGroup.Add(newPerson);
                }
            }
            catch (Exception ex)
            {
                await Util.GenericApiCallExceptionHandler(ex, AppResourcesHelper.GetString("PersonGroupDetailsPage_ErrorBatchTrainFailure"));
            }

            this.progressControl.IsActive = false;
        }
Example #7
0
        private void UpdateUIForNoDriverDetected()
        {
            this.faceLantencyDebugText.Text    = "";
            this.visionLantencyDebugText.Text  = "";
            this.highLatencyWarning.Visibility = Visibility.Collapsed;

            this.driverId.Text            = AppResourcesHelper.GetString("RealtimeDriverMonitoring_AlertNoFaces");
            this.sleeping.Visibility      = this.lookingAway.Visibility = this.yawning.Visibility = this.objectDistraction.Visibility = Visibility.Collapsed;
            this.headPoseIndicator.Margin = new Thickness(0);
        }
Example #8
0
        private async Task DeletePersonGroupAsync()
        {
            try
            {
                await FaceServiceHelper.DeletePersonGroupAsync(this.CurrentPersonGroup.PersonGroupId);

                this.Frame.GoBack();
            }
            catch (Exception ex)
            {
                await Util.GenericApiCallExceptionHandler(ex, AppResourcesHelper.GetString("PersonGroupDetailsPage_ErrorDeleteGroup"));
            }
        }
Example #9
0
 /// <summary>
 /// Map a news to an generic item
 /// </summary>
 /// <param name="element">News to map</param>
 /// <returns>Corresponding generic item</returns>
 public VisualGenericItem Map(News element)
 {
     return(new VisualGenericItem
     {
         Id = element.Id,
         Title = element.Title,
         Subtitle = string.Format("{0}, {1} {2} {3}", DateFormatter.Format(element.DateTime),
                                  AppResourcesHelper.GetString("BY"),
                                  element.Member.FirstName,
                                  element.Member.LastName),
         ImageUrl = element.ImageUrl,
         Type = element.GetType().Name
     });
 }
        /// <summary>
        /// Open the selected item in the related master page
        /// </summary>
        /// <param name="group">Group and group items to display</param>
        private void GoToMasterPage(VisualGenericGroup group)
        {
            IDictionary <string, Func <Type> > pages = new Dictionary <string, Func <Type> >
            {
                { AppResourcesHelper.GetString("LBL_NEWS"), () => typeof(NewsPage) },
                { AppResourcesHelper.GetString("LBL_BUREAU"), () => typeof(MembersPage) },
                { AppResourcesHelper.GetString("LBL_PROJECTS"), () => typeof(ProjectsPage) },
                { AppResourcesHelper.GetString("LBL_CONFERENCES"), () => typeof(ConferencesPage) },
                { AppResourcesHelper.GetString("LBL_SALONS"), () => typeof(ShowsPage) }
            };

            Type type = pages[group.Title]();

            Frame.Navigate(type);
        }
Example #11
0
        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            EnterKioskMode();

            if (string.IsNullOrEmpty(SettingsHelper.Instance.FaceApiKey))
            {
                await new MessageDialog(AppResourcesHelper.GetString("AutomaticPhotoCapturePage_MissingAPI_Content"), AppResourcesHelper.GetString("AutomaticPhotoCapturePage_MissingAPI_Title")).ShowAsync();
            }
            else
            {
                await this.cameraControl.StartStreamAsync();
            }

            base.OnNavigatedTo(e);
        }
Example #12
0
        private async Task CreatePersonAsync(string name)
        {
            try
            {
                await FaceServiceHelper.CreatePersonAsync(this.CurrentPersonGroup.PersonGroupId, Util.CapitalizeString(name));

                await this.LoadPersonsInCurrentGroup();

                this.DismissFlyout();
            }
            catch (Exception e)
            {
                await Util.GenericApiCallExceptionHandler(e, AppResourcesHelper.GetString("PersonGroupDetailsPage_ErrorCreatePerson"));
            }
        }
Example #13
0
        /// <summary>
        /// Constructor. Resolve IoC dependencies, create the menu and the commands
        /// </summary>
        public MainViewModel()
        {
            // Resolve Ioc dependencies
            using (ILifetimeScope scope = ViewModelLocator.Container.BeginLifetimeScope())
            {
                _modelConference = scope.Resolve <IReadableLimitable <Conference> >();
                _modelMember     = scope.Resolve <IReadableMember>();
                _modelNews       = scope.Resolve <IReadableLimitable <News> >();
                _modelConference = scope.Resolve <IReadableLimitable <Conference> >();
                _modelProject    = scope.Resolve <IReadableLimitable <Project> >();
                _modelShow       = scope.Resolve <IReadableLimitable <Show> >();
            }

            // Create the menu
            Menu = new VisualMenu
            {
                Groups = new ObservableCollection <VisualGenericGroup>
                {
                    new VisualGenericGroup {
                        Title = AppResourcesHelper.GetString("LBL_NEWS")
                    },
                    new VisualGenericGroup {
                        Title = AppResourcesHelper.GetString("LBL_BUREAU")
                    },
                    new VisualGenericGroup {
                        Title = AppResourcesHelper.GetString("LBL_PROJECTS")
                    },
                    new VisualGenericGroup {
                        Title = AppResourcesHelper.GetString("LBL_CONFERENCES")
                    },
                    new VisualGenericGroup {
                        Title = AppResourcesHelper.GetString("LBL_SALONS")
                    }
                }
            };

            // Create commands
            LoadMenuCommand      = new AsyncDelegateCommand(LoadMenuAsync);
            LoadMoreItemsCommand = new AsyncDelegateCommand <string>(LoadMoreItemsAsync);

            GoToMasterPageCommand  = new RelayCommand <VisualGenericGroup>(GoToMasterPage);
            GoToDetailsPageCommand = new RelayCommand <VisualGenericItem>(GoToDetailsPage);
            GoToAboutPageCommand   = new RelayCommand <object>(GoToAboutPage);

            GoToSocialPageCommand = new RelayCommand <Uri>(GoToSocialNetworkPage);
            PinCommand            = new RelayCommand <PinnableObject>(Pin);
        }
Example #14
0
        private async Task LoadPersonsInCurrentGroup()
        {
            this.PersonsInCurrentGroup.Clear();

            try
            {
                Person[] personsInGroup = await FaceServiceHelper.GetPersonsAsync(this.CurrentPersonGroup.PersonGroupId);

                foreach (Person person in personsInGroup.OrderBy(p => p.Name))
                {
                    this.PersonsInCurrentGroup.Add(person);
                }
            }
            catch (Exception e)
            {
                await Util.GenericApiCallExceptionHandler(e, AppResourcesHelper.GetString("PersonGroupDetailsPage_ErrorLoadFailed"));
            }
        }
Example #15
0
        private async void StartDriverIdAsync(ImageAnalyzer e)
        {
            if (this.isProcessingDriverId)
            {
                return;
            }

            if (!e.DetectedFaces.Any())
            {
                this.UpdateUIForNoDriverDetected();
                return;
            }

            await Task.WhenAll(e.IdentifyFacesAsync(), e.FindSimilarPersistedFacesAsync());

            SimilarFaceMatch faceMatch = e.SimilarFaceMatches.FirstOrDefault();

            if (faceMatch != null)
            {
                string name = AppResourcesHelper.GetString("RealtimeDriverMonitoring_AlertUnknownName");

                IdentifiedPerson p = e.IdentifiedPersons.FirstOrDefault(f => f.FaceId == faceMatch.Face.FaceId);
                if (p != null)
                {
                    name = p.Person.Name;
                }
                else
                {
                    if (faceMatch.Face.FaceAttributes.Gender == "male")
                    {
                        name = AppResourcesHelper.GetString("RealtimeDriverMonitoring_AlertUnknownMale");
                    }
                    else if (faceMatch.Face.FaceAttributes.Gender == "female")
                    {
                        name = AppResourcesHelper.GetString("RealtimeDriverMonitoring_AlertUnknownFemale");
                    }
                }

                this.driverId.Text = string.Format("{0}\nFace Id: {1}", name, faceMatch.SimilarPersistedFace.PersistedFaceId.ToString("N").Substring(0, 4));
            }

            this.isProcessingDriverId = false;
        }
Example #16
0
        private async void StartCaptioningAsync(ImageAnalyzer e)
        {
            if (this.isDescribingPhoto)
            {
                return;
            }

            DateTime start = DateTime.Now;

            await e.DescribeAsync();

            TimeSpan latency = DateTime.Now - start;

            this.visionLantencyDebugText.Text  = string.Format("Vision API latency: {0}ms", (int)latency.TotalMilliseconds);
            this.highLatencyWarning.Visibility = latency.TotalSeconds <= 3 ? Visibility.Collapsed : Visibility.Visible;

            string desc = e.AnalysisResult.Description?.Captions?[0].Text;

            if (string.IsNullOrEmpty(desc) || !this.visionToggle.IsOn)
            {
                this.objectDistraction.Visibility = Visibility.Collapsed;
            }
            else
            {
                this.visionAPICaptionTextBlock.Text = string.Format("{0} ({1}%)", desc, (int)(e.AnalysisResult.Description.Captions[0].Confidence * 100));

                string distraction = string.Empty;
                if (desc.Contains("phone"))
                {
                    distraction = AppResourcesHelper.GetString("RealtimeDriverMonitoring_AlertPhone");
                }
                else if (desc.Contains("banana"))
                {
                    distraction = AppResourcesHelper.GetString("RealtimeDriverMonitoring_AlertBanana");
                }

                this.objectDistraction.Text       = distraction;
                this.objectDistraction.Visibility = distraction != "" ? Visibility.Visible : Visibility.Collapsed;
            }

            this.isDescribingPhoto = false;
        }
Example #17
0
        private async Task PickFolderASync()
        {
            try
            {
                FolderPicker folderPicker = new FolderPicker();
                folderPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
                folderPicker.FileTypeFilter.Add(".jpeg");
                folderPicker.FileTypeFilter.Add(".bmp");
                autoTrainFolder = await folderPicker.PickSingleFolderAsync();

                if (autoTrainFolder != null)
                {
                    await ImportFromFolderAndFilesAsync();
                }
            }
            catch (Exception ex)
            {
                await Util.GenericApiCallExceptionHandler(ex, AppResourcesHelper.GetString("PersonGroupDetailsPage_ErrorPickFolder"));
            }
        }
Example #18
0
        private async void CameraControl_AutoCaptureStateChanged(object sender, AutoCaptureState e)
        {
            switch (e)
            {
            case AutoCaptureState.WaitingForFaces:
                this.cameraGuideBallon.Opacity = 1;
                this.cameraGuideText.Text      = AppResourcesHelper.GetString("AutomaticPhotoCapturePage_Start.Text");
                this.cameraGuideHost.Opacity   = 1;
                break;

            case AutoCaptureState.WaitingForStillFaces:
                this.cameraGuideText.Text = AppResourcesHelper.GetString("AutomaticPhotoCapturePage_Hold");
                break;

            case AutoCaptureState.ShowingCountdownForCapture:
                this.cameraGuideText.Text      = "";
                this.cameraGuideBallon.Opacity = 0;

                this.cameraGuideCountdownHost.Opacity = 1;
                this.countDownTextBlock.Text          = "3";
                await Task.Delay(750);

                this.countDownTextBlock.Text = "2";
                await Task.Delay(750);

                this.countDownTextBlock.Text = "1";
                await Task.Delay(750);

                this.cameraGuideCountdownHost.Opacity = 0;

                this.ProcessCameraCapture(await this.cameraControl.TakeAutoCapturePhoto());
                break;

            case AutoCaptureState.ShowingCapturedPhoto:
                this.cameraGuideHost.Opacity = 0;
                break;

            default:
                break;
            }
        }
        /// <summary>
        /// Search in conferences
        /// </summary>
        private async Task SearchConferencesAsync()
        {
            IsLoading = true;

            IList <Conference> conferences = await _modelConferences.SearchAsync(Keywords);

            if (conferences != null && conferences.Count > 0)
            {
                IMapper <Conference>      mapper             = new GenericConferenceMapper();
                IList <VisualGenericItem> genericConferences = mapper.Map(conferences);

                Results.Groups.Insert(Results.Groups.Count, new VisualGenericGroup
                {
                    Title         = AppResourcesHelper.GetString("LBL_CONFERENCES"),
                    Items         = new ObservableCollection <VisualGenericItem>(genericConferences),
                    IsFullyLoaded = true
                });
            }

            IsLoading = false;
        }
        /// <summary>
        /// Search in shows
        /// </summary>
        private async Task SearchShowsAsync()
        {
            IsLoading = true;

            IList <Show> salons = await _modelShows.SearchAsync(Keywords);

            if (salons != null && salons.Count > 0)
            {
                IMapper <Show>            mapper      = new GenericShowMapper();
                IList <VisualGenericItem> genericShow = mapper.Map(salons);

                Results.Groups.Insert(Results.Groups.Count, new VisualGenericGroup
                {
                    Title         = AppResourcesHelper.GetString("LBL_SALONS"),
                    Items         = new ObservableCollection <VisualGenericItem>(genericShow),
                    IsFullyLoaded = true
                });
            }

            IsLoading = false;
        }
        /// <summary>
        /// Search in news
        /// </summary>
        private async Task SearchNewsAsync()
        {
            IsLoading = true;

            IList <News> news = await _modelNews.SearchAsync(Keywords);

            if (news != null && news.Count > 0)
            {
                IMapper <News>            mapper      = new GenericNewsMapper();
                IList <VisualGenericItem> genericNews = mapper.Map(news);

                Results.Groups.Insert(Results.Groups.Count, new VisualGenericGroup
                {
                    Title         = AppResourcesHelper.GetString("LBL_NEWS"),
                    Items         = new ObservableCollection <VisualGenericItem>(genericNews),
                    IsFullyLoaded = true
                });
            }

            IsLoading = false;
        }
Example #22
0
        /// <summary>
        /// Load the shows list from the model
        /// </summary>
        private async Task LoadShowsAsync()
        {
            IsLoading = true;

            IEnumerable <Show> salons = await _modelShow.GetAsync(0, 8);

            if (salons != null)
            {
                IMapper <Show>            mapper       = new GenericShowMapper();
                IList <VisualGenericItem> genericShows = mapper.Map(salons);

                Menu.Groups.RemoveAt(4);

                Menu.Groups.Insert(4, new VisualGenericGroup
                {
                    Title         = AppResourcesHelper.GetString("LBL_SALONS"),
                    Items         = new ObservableCollection <VisualGenericItem>(genericShows),
                    IsFullyLoaded = genericShows.Count < 8
                });
            }

            IsLoading = false;
        }
Example #23
0
        /// <summary>
        /// Load the projects list from the model
        /// </summary>
        private async Task LoadProjectsAsync()
        {
            IsLoading = true;

            IEnumerable <Project> projets = await _modelProject.GetAsync(0, 8);

            if (projets != null)
            {
                IMapper <Project>         mapper          = new GenericProjectMapper();
                IList <VisualGenericItem> genericProjects = mapper.Map(projets);

                Menu.Groups.RemoveAt(3);

                Menu.Groups.Insert(3, new VisualGenericGroup
                {
                    Title         = AppResourcesHelper.GetString("LBL_PROJECTS"),
                    Items         = new ObservableCollection <VisualGenericItem>(genericProjects),
                    IsFullyLoaded = genericProjects.Count < 8
                });
            }

            IsLoading = false;
        }
Example #24
0
        /// <summary>
        /// Load the news list from the model
        /// </summary>
        private async Task LoadNewsAsync()
        {
            IsLoading = true;

            IEnumerable <News> news = await _modelNews.GetAsync(0, 8);

            if (news != null)
            {
                IMapper <News>            mapper      = new GenericNewsMapper();
                IList <VisualGenericItem> genericNews = mapper.Map(news);

                Menu.Groups.RemoveAt(0);

                Menu.Groups.Insert(0, new VisualGenericGroup
                {
                    Title         = AppResourcesHelper.GetString("LBL_NEWS"),
                    Items         = new ObservableCollection <VisualGenericItem>(genericNews),
                    IsFullyLoaded = genericNews.Count < 8
                });
            }

            IsLoading = false;
        }
Example #25
0
        /// <summary>
        /// Load the conferences list from the model
        /// </summary>
        private async Task LoadConferencesAsync()
        {
            IsLoading = true;

            IEnumerable <Conference> conferences = await _modelConference.GetAsync(0, 8);

            if (conferences != null)
            {
                IMapper <Conference>      mapper             = new GenericConferenceMapper();
                IList <VisualGenericItem> genericConferences = mapper.Map(conferences);

                Menu.Groups.RemoveAt(2);

                Menu.Groups.Insert(2, new VisualGenericGroup
                {
                    Title         = AppResourcesHelper.GetString("LBL_CONFERENCES"),
                    Items         = new ObservableCollection <VisualGenericItem>(genericConferences),
                    IsFullyLoaded = genericConferences.Count < 8
                });
            }

            IsLoading = false;
        }
Example #26
0
        /// <summary>
        /// Load the bureau list from the model
        /// </summary>
        private async Task LoadBureauAsync()
        {
            IsLoading = true;

            IEnumerable <Member> members = await _modelMember.GetBureauAsync();

            if (members != null)
            {
                IMapper <Member>          mapper         = new GenericMemberMapper();
                IList <VisualGenericItem> genericMembers = mapper.Map(members);

                Menu.Groups.RemoveAt(1);

                Menu.Groups.Insert(1, new VisualGenericGroup
                {
                    Title         = AppResourcesHelper.GetString("LBL_BUREAU"),
                    Items         = new ObservableCollection <VisualGenericItem>(genericMembers),
                    IsFullyLoaded = true
                });
            }

            IsLoading = false;
        }
Example #27
0
 private async void OnSelectFolderButtonClicked(object sender, RoutedEventArgs e)
 {
     await Util.ConfirmActionAndExecute(AppResourcesHelper.GetString("PersonGroupDetailsPage_ConfirmSelectFolder"), async() => { await PickFolderASync(); });
 }
Example #28
0
 private async void OnDeletePersonGroupClicked(object sender, RoutedEventArgs e)
 {
     await Util.ConfirmActionAndExecute(AppResourcesHelper.GetString("PersonGroupDetailsPage_ConfirmDeleteGroup"), async() => { await DeletePersonGroupAsync(); });
 }