diff --git a/NumberRecognizer/NumberRecognizer.App/Common/BooleanToVisibilityConverter.cs b/NumberRecognizer/NumberRecognizer.App/Common/BooleanToVisibilityConverter.cs
new file mode 100644
index 0000000..8e2bff4
--- /dev/null
+++ b/NumberRecognizer/NumberRecognizer.App/Common/BooleanToVisibilityConverter.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.Graphics.Display;
+using Windows.UI.ViewManagement;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Data;
+
+namespace NumberRecognizer.App.Common
+{
+ ///
+ /// Wertkonverter, der TRUE in und FALSE in
+ /// übersetzt.
+ ///
+ public class BooleanToVisibilityConverter : IValueConverter
+ {
+ ///
+ /// Ändert die Quelldaten vor der Übergabe an das Ziel zur Anzeige in der Benutzeroberfläche.
+ ///
+ /// Die Quelldaten, die ans Ziel übergeben werden.
+ /// Der Typ der Zieleigenschaft. Dadurch wird ein anderer Typ verwendet, abhängig davon, ob Sie mit Microsoft .NET oder Visual C++-Komponentenerweiterungen (C++/CX) programmieren. Siehe Hinweise.
+ /// Ein optionaler Parameter, der in der Konverterlogik verwendet wird.
+ /// Die Sprache der Konvertierung.
+ ///
+ /// Der Wert, der an die Zielabhängigkeitseigenschaft übergeben werden soll.
+ ///
+ public object Convert(object value, Type targetType, object parameter, string language)
+ {
+ if (parameter != null)
+ {
+ return (value is bool && (bool)value) ? Visibility.Collapsed : Visibility.Visible;
+ }
+ return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ ///
+ /// Ändert die Zieldaten vor der Übergabe an das Quellobjekt. Diese Methode wird nur in TwoWay-Bindungen aufgerufen.
+ ///
+ /// Die Zieldaten, die an die Quelle übergeben werden.
+ /// Der Typ der Zieleigenschaft, angegeben durch eine Hilfestruktur, die den Typnamen umschließt.
+ /// Ein optionaler Parameter, der in der Konverterlogik verwendet wird.
+ /// Die Sprache der Konvertierung.
+ ///
+ /// Der Wert, der an das Quellobjekt weitergeleitet wird.
+ ///
+ public object ConvertBack(object value, Type targetType, object parameter, string language)
+ {
+ return value is Visibility && (Visibility)value == Visibility.Visible;
+ }
+ }
+}
diff --git a/NumberRecognizer/NumberRecognizer.App/Control/InkCanvasRT.cs b/NumberRecognizer/NumberRecognizer.App/Control/InkCanvasRT.cs
index 7e6b0c2..219bb96 100644
--- a/NumberRecognizer/NumberRecognizer.App/Control/InkCanvasRT.cs
+++ b/NumberRecognizer/NumberRecognizer.App/Control/InkCanvasRT.cs
@@ -138,6 +138,14 @@ private static double Distance(Point p1, Point p2)
/// The source of the event.
/// The instance containing the event data.
private void InkCanvasRT_RightTapped(object sender, RightTappedRoutedEventArgs e)
+ {
+ ClearInk();
+ }
+
+ ///
+ /// Clears the ink canvas.
+ ///
+ public void ClearInk()
{
this.Children.Clear();
this.inkManager = new InkManager();
diff --git a/NumberRecognizer/NumberRecognizer.App/DataModel/LocalTrainingImage.cs b/NumberRecognizer/NumberRecognizer.App/DataModel/LocalTrainingImage.cs
new file mode 100644
index 0000000..940cd3f
--- /dev/null
+++ b/NumberRecognizer/NumberRecognizer.App/DataModel/LocalTrainingImage.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Windows.Storage;
+using NumberRecognizer.Cloud.Contract.Data;
+
+namespace NumberRecognizer.App.DataModel
+{
+ public class LocalTrainingImage
+ {
+ public TrainingImage ImageData { get; set; }
+
+ public String LocalImagePath { get; set; }
+ }
+}
diff --git a/NumberRecognizer/NumberRecognizer.App/DataModel/LocalTrainingImageGroup.cs b/NumberRecognizer/NumberRecognizer.App/DataModel/LocalTrainingImageGroup.cs
new file mode 100644
index 0000000..fa94084
--- /dev/null
+++ b/NumberRecognizer/NumberRecognizer.App/DataModel/LocalTrainingImageGroup.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using GalaSoft.MvvmLight;
+
+namespace NumberRecognizer.App.DataModel
+{
+ public class LocalTrainingImageGroup : ViewModelBase
+ {
+ ///
+ /// The titel
+ ///
+ private string title;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The unique identifier.
+ /// The title.
+ public LocalTrainingImageGroup(string uniqueId, string title)
+ {
+ this.UniqueId = uniqueId;
+ this.Title = title;
+ this.Items = new ObservableCollection();
+ }
+
+ ///
+ /// Gets the unique identifier.
+ ///
+ ///
+ /// The unique identifier.
+ ///
+ public string UniqueId { get; private set; }
+
+ ///
+ /// Gets the title.
+ ///
+ ///
+ /// The title.
+ ///
+ public string Title
+ {
+ get
+ {
+ return title;
+ }
+ private set
+ {
+ this.title = value;
+ RaisePropertyChanged(() => Title);
+ }
+ }
+
+ ///
+ /// Gets the items.
+ ///
+ ///
+ /// The items.
+ ///
+ public ObservableCollection Items { get; set; }
+ }
+}
diff --git a/NumberRecognizer/NumberRecognizer.App/Help/ImageHelperRT.cs b/NumberRecognizer/NumberRecognizer.App/Help/ImageHelperRT.cs
index 6f64b6a..8bcea1e 100644
--- a/NumberRecognizer/NumberRecognizer.App/Help/ImageHelperRT.cs
+++ b/NumberRecognizer/NumberRecognizer.App/Help/ImageHelperRT.cs
@@ -150,7 +150,7 @@ public static byte[] GetByteArrayFrom2DPixelArrayAsync(double[,] pixelArray2D)
///
/// The red, green, blue, alpha byte array as bitmap image asynchronous.
///
- public static async Task SaveRGBAByteArrayAsBitmapImageAsync(byte[] rgbaByteArray, double width, double height, string name)
+ public static async Task SaveRGBAByteArrayAsBitmapImageAsync(byte[] rgbaByteArray, double width, double height, string name)
{
var storageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(name + ".png", CreationCollisionOption.ReplaceExisting);
@@ -161,6 +161,8 @@ public static async Task SaveRGBAByteArrayAsBitmapImageAsync(byte[] rgbaByteArra
bitmapEncoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.NearestNeighbor;
await bitmapEncoder.FlushAsync();
}
+
+ return storageFile.Path;
}
///
diff --git a/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App.csproj b/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App.csproj
index dea49a4..4f03df2 100644
--- a/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App.csproj
+++ b/NumberRecognizer/NumberRecognizer.App/NumberRecognizer.App.csproj
@@ -111,7 +111,10 @@
App.xaml
+
+
+
@@ -122,6 +125,7 @@
+
GroupedNetworksPage.xaml
@@ -139,6 +143,9 @@
RecognizePage.xaml
+
+ ValidateTrainingDataPage.xaml
+
@@ -208,6 +215,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService4.xsd b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService4.xsd
index 28dfc4d..3dd76bb 100644
--- a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService4.xsd
+++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/NumberRecognizerService4.xsd
@@ -1,4 +1,4 @@
-
+
@@ -13,7 +13,7 @@
-
+
@@ -22,14 +22,14 @@
-
+
-
+
-
+
@@ -39,10 +39,10 @@
-
+
-
+
diff --git a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/Reference.cs b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/Reference.cs
index aaf9960..d049792 100644
--- a/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/Reference.cs
+++ b/NumberRecognizer/NumberRecognizer.App/Service References/NumberRecognizerService/Reference.cs
@@ -21,7 +21,7 @@ public interface INumberRecognizerService {
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/INumberRecognizerService/GetNetworks", ReplyAction="http://tempuri.org/INumberRecognizerService/GetNetworksResponse")]
System.Threading.Tasks.Task> GetNetworksAsync();
- [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/INumberRecognizerService/CreateNetwork", ReplyAction="http://tempuri.org/INumberRecognizerService/CreateNetworkResponse")]
+ [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/INumberRecognizerService/ValidateTrainingData", ReplyAction="http://tempuri.org/INumberRecognizerService/CreateNetworkResponse")]
System.Threading.Tasks.Task CreateNetworkAsync(string networkName, string username, System.Collections.ObjectModel.ObservableCollection individualTrainingsData);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/INumberRecognizerService/CreateNetworkWithTrainingDataCopy", ReplyAction="http://tempuri.org/INumberRecognizerService/CreateNetworkWithTrainingDataCopyResp" +
diff --git a/NumberRecognizer/NumberRecognizer.App/Style/AppStyle.xaml b/NumberRecognizer/NumberRecognizer.App/Style/AppStyle.xaml
index 4d07261..850b2d8 100644
--- a/NumberRecognizer/NumberRecognizer.App/Style/AppStyle.xaml
+++ b/NumberRecognizer/NumberRecognizer.App/Style/AppStyle.xaml
@@ -27,4 +27,15 @@
+
+
+
diff --git a/NumberRecognizer/NumberRecognizer.App/View/CreateNetworkPage.xaml b/NumberRecognizer/NumberRecognizer.App/View/CreateNetworkPage.xaml
index 1480f7b..8256dec 100644
--- a/NumberRecognizer/NumberRecognizer.App/View/CreateNetworkPage.xaml
+++ b/NumberRecognizer/NumberRecognizer.App/View/CreateNetworkPage.xaml
@@ -15,6 +15,8 @@
4.0
40.0
100
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NumberRecognizer/NumberRecognizer.App/View/ValidateTrainingDataPage.xaml.cs b/NumberRecognizer/NumberRecognizer.App/View/ValidateTrainingDataPage.xaml.cs
new file mode 100644
index 0000000..08ec65e
--- /dev/null
+++ b/NumberRecognizer/NumberRecognizer.App/View/ValidateTrainingDataPage.xaml.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using NumberRecognizer.App.Common;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+// Die Elementvorlage für die Seite "Gruppierte Elemente" ist unter http://go.microsoft.com/fwlink/?LinkId=234231 dokumentiert.
+using NumberRecognizer.App.DataModel;
+using NumberRecognizer.App.ViewModel;
+
+namespace NumberRecognizer.App.View
+{
+ ///
+ /// Eine Seite, auf der eine gruppierte Auflistung von Elementen angezeigt wird.
+ ///
+ public sealed partial class ValidateTrainingDataPage : Page
+ {
+ private NavigationHelper navigationHelper;
+
+ ///
+ /// Dies kann in ein stark typisiertes Anzeigemodell geändert werden.
+ ///
+ public ValidateTrainingDataViewModel DefaultViewModel { get; set; }
+
+ ///
+ /// NavigationHelper wird auf jeder Seite zur Unterstützung bei der Navigation verwendet und
+ /// Verwaltung der Prozesslebensdauer
+ ///
+ public NavigationHelper NavigationHelper
+ {
+ get
+ {
+ return this.navigationHelper;
+ }
+ }
+
+ public ValidateTrainingDataPage()
+ {
+ this.InitializeComponent();
+ this.navigationHelper = new NavigationHelper(this);
+ this.navigationHelper.LoadState += navigationHelper_LoadState;
+ }
+
+ ///
+ /// Füllt die Seite mit Inhalt auf, der bei der Navigation übergeben wird. Gespeicherte Zustände werden ebenfalls
+ /// bereitgestellt, wenn eine Seite aus einer vorherigen Sitzung neu erstellt wird.
+ ///
+ ///
+ /// Die Quelle des Ereignisses, normalerweise
+ ///
+ /// Ereignisdaten, die die Navigationsparameter bereitstellen, die an
+ /// als diese Seite ursprünglich angefordert wurde und
+ /// ein Wörterbuch des Zustands, der von dieser Seite während einer früheren
+ /// beibehalten wurde. Der Zustand ist beim ersten Aufrufen einer Seite NULL.
+ private void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
+ {
+ var localTrainingData = (Dictionary>)e.NavigationParameter;
+
+ DefaultViewModel = new ValidateTrainingDataViewModel(localTrainingData);
+
+ this.DataContext = DefaultViewModel;
+ }
+
+ #region NavigationHelper-Registrierung
+
+ /// Die in diesem Abschnitt bereitgestellten Methoden lassen sich einfach für Folgendes verwenden:
+ /// Reaktion von NavigationHelper auf die Navigationsmethoden der Seite.
+ ///
+ /// Platzieren von seitenspezifischer Logik in Ereignishandlern für
+ ///
+ /// und .
+ /// Der Navigationsparameter ist in der LoadState-Methode verfügbar
+ /// zusätzlich zum Seitenzustand, der während einer früheren Sitzung beibehalten wurde.
+
+ protected override void OnNavigatedTo(NavigationEventArgs e)
+ {
+ navigationHelper.OnNavigatedTo(e);
+ }
+
+ protected override void OnNavigatedFrom(NavigationEventArgs e)
+ {
+ navigationHelper.OnNavigatedFrom(e);
+ }
+
+ #endregion
+ }
+}
diff --git a/NumberRecognizer/NumberRecognizer.App/ViewModel/CreateNetworkViewModel.cs b/NumberRecognizer/NumberRecognizer.App/ViewModel/CreateNetworkViewModel.cs
index ccae95d..817bb60 100644
--- a/NumberRecognizer/NumberRecognizer.App/ViewModel/CreateNetworkViewModel.cs
+++ b/NumberRecognizer/NumberRecognizer.App/ViewModel/CreateNetworkViewModel.cs
@@ -14,7 +14,9 @@
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using NumberRecognizer.App.Control;
+using NumberRecognizer.App.DataModel;
using NumberRecognizer.App.Help;
+using NumberRecognizer.App.View;
using NumberRecognizer.Cloud.Contract.Data;
using NumberRecognizer.Labeling;
@@ -25,12 +27,13 @@ public class CreateNetworkViewModel : ViewModelBase
///
/// The command create network
///
- private ICommand cmdCreateNetwork;
+ private ICommand cmdValidateTrainingData;
///
/// The command delete network
///
- private ICommand cmdCancel;
+ private RelayCommand cmdClearInk;
+
///
/// The canvas list
@@ -42,6 +45,11 @@ public class CreateNetworkViewModel : ViewModelBase
///
private string networkName;
+ ///
+ /// The show error
+ ///
+ private bool isValidationError;
+
#region Constructor
///
@@ -49,6 +57,7 @@ public class CreateNetworkViewModel : ViewModelBase
///
public CreateNetworkViewModel()
{
+ IsValidationError = false;
canvasList = new List();
InitializeNetworkName();
LoadCommands();
@@ -63,7 +72,8 @@ public CreateNetworkViewModel()
///
private void LoadCommands()
{
- CreateNetwork = new RelayCommand(() => App.Frame.Navigate(typeof(CreateNetworkPage)));
+ ValidateTrainingData = new RelayCommand(ExecuteValidateTrainingData);
+ ClearInk = new RelayCommand((string inkCanvasIndex) => canvasList[Convert.ToInt32(inkCanvasIndex)].ClearInk());
}
///
@@ -71,7 +81,7 @@ private void LoadCommands()
///
private async void InitializeNetworkName()
{
- NetworkName = string.Format("{0}_{1}", await UserInformation.GetLastNameAsync(), DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss"));
+ NetworkName = string.Format("{0}_{1}", await UserInformation.GetLastNameAsync(), DateTime.Now.ToFileTime());
}
#endregion
@@ -115,6 +125,25 @@ public string NetworkName
}
}
+ ///
+ /// Gets or sets a value indicating whether [is validation error].
+ ///
+ ///
+ /// true if [is validation error]; otherwise, false.
+ ///
+ public bool IsValidationError
+ {
+ get
+ {
+ return isValidationError;
+ }
+ set
+ {
+ isValidationError = value;
+ RaisePropertyChanged(() => IsValidationError);
+ }
+ }
+
#endregion
#region Commands
@@ -125,16 +154,16 @@ public string NetworkName
///
/// The add network.
///
- public ICommand CreateNetwork
+ public ICommand ValidateTrainingData
{
get
{
- return cmdCreateNetwork;
+ return cmdValidateTrainingData;
}
set
{
- cmdCreateNetwork = value;
- RaisePropertyChanged(() => CreateNetwork);
+ cmdValidateTrainingData = value;
+ RaisePropertyChanged(() => ValidateTrainingData);
}
}
@@ -144,16 +173,16 @@ public ICommand CreateNetwork
///
/// The refresh networks.
///
- public ICommand Cancel
+ public RelayCommand ClearInk
{
get
{
- return cmdCancel;
+ return cmdClearInk;
}
set
{
- cmdCancel= value;
- RaisePropertyChanged(() => Cancel);
+ cmdClearInk = value;
+ RaisePropertyChanged(() => ClearInk);
}
}
@@ -162,10 +191,12 @@ public ICommand Cancel
///
/// Handles the Click event of the NextButton control.
///
- /// The source of the event.
- /// The instance containing the event data.
- private async Task> GetTrainingData(object sender, Windows.UI.Xaml.RoutedEventArgs e)
+ ///
+ private async Task>> GetTrainingData()
{
+ Dictionary> trainingData = new Dictionary>();
+ int pattern = 0;
+
foreach (InkCanvasRT inkCanvas in canvasList)
{
var renderTargetBitmap = new RenderTargetBitmap();
@@ -178,6 +209,8 @@ private async Task> GetTrainingData(object sender
double canvasHeight = inkCanvas.ActualHeight;
double[,] canvasPixels = await ImageHelperRT.Get2DPixelArrayFromByteArrayAsync(canvasBytes, canvasWidth, canvasHeight);
+ trainingData.Add(pattern, new List());
+
inkCanvas.ConnectedComponentLabeling = new ConnectedComponentLabeling(canvasPixels, 0.0);
foreach (ConnectedComponent connectedComponent in inkCanvas.ConnectedComponentLabeling.ConnectedComponents)
@@ -214,21 +247,55 @@ private async Task> GetTrainingData(object sender
}
}
- byte[] orgRGBABytes = ImageHelperRT.GetRGBAByteArrayFromByteArrayAsync(orgBytes, Colors.Black);
- await ImageHelperRT.SaveRGBAByteArrayAsBitmapImageAsync(orgRGBABytes, mbr.Width, mbr.Height, inkCanvas.Name + "_org");
- connectedComponent.Pixels = await ImageHelperRT.Get2DPixelArrayFromByteArrayAsync(orgBytes, mbr.Width, mbr.Height);
+ //byte[] orgRGBABytes = ImageHelperRT.GetRGBAByteArrayFromByteArrayAsync(orgBytes, Colors.Black);
+ //await ImageHelperRT.SaveRGBAByteArrayAsBitmapImageAsync(orgRGBABytes, mbr.Width, mbr.Height, inkCanvas.Name + "_org");
+ //connectedComponent.Pixels = await ImageHelperRT.Get2DPixelArrayFromByteArrayAsync(orgBytes, mbr.Width, mbr.Height);
byte[] scaRGBABytes = ImageHelperRT.GetRGBAByteArrayFromByteArrayAsync(scaBytes, Colors.Black);
scaRGBABytes = await ImageHelperRT.ScaleRGBAByteArrayAsync(scaRGBABytes, mbr.Size, mbr.Size, ImageHelperRT.ImageWidth, ImageHelperRT.ImageHeight);
scaBytes = await ImageHelperRT.GetByteArrayFromRGBAByteArrayAsync(scaRGBABytes, inkCanvas.ForegroundColor);
- await ImageHelperRT.SaveRGBAByteArrayAsBitmapImageAsync(scaRGBABytes, ImageHelperRT.ImageWidth, ImageHelperRT.ImageHeight, inkCanvas.Name + "_sca");
- connectedComponent.ScaledPixels = await ImageHelperRT.Get2DPixelArrayFromByteArrayAsync(scaBytes, ImageHelperRT.ImageWidth, ImageHelperRT.ImageHeight);
+ double[,] pixels = await ImageHelperRT.Get2DPixelArrayFromByteArrayAsync(scaBytes, ImageHelperRT.ImageWidth, ImageHelperRT.ImageHeight);
+ connectedComponent.ScaledPixels = pixels;
+
+ //save image to storage
+ string imagename = string.Format("{0}_{1}", networkName, pattern);
+ string path = await ImageHelperRT.SaveRGBAByteArrayAsBitmapImageAsync(scaRGBABytes, ImageHelperRT.ImageWidth, ImageHelperRT.ImageHeight, imagename);
+
+ var imageData = new TrainingImage(){
+ Height = Convert.ToInt32(ImageHelperRT.ImageHeight),
+ Width = Convert.ToInt32(ImageHelperRT.ImageWidth),
+ Pattern = pattern.ToString()
+ };
+
+ imageData.TransformFrom2DArrayToImageData(pixels);
+
+ trainingData[pattern].Add(new LocalTrainingImage()
+ {
+ LocalImagePath = path,
+ ImageData = imageData
+ });
}
+
+ pattern++;
}
- //TODO
- return null;
+ return trainingData;
+
}
+ ///
+ /// Executes the validate training data.
+ ///
+ private async void ExecuteValidateTrainingData()
+ {
+ var trainData = await GetTrainingData();
+
+ IsValidationError = !trainData.All(keyvalpair => keyvalpair.Value.Count > 0);
+
+ if(!IsValidationError)
+ {
+ App.Frame.Navigate(typeof(ValidateTrainingDataPage), trainData);
+ }
+ }
}
}
diff --git a/NumberRecognizer/NumberRecognizer.App/ViewModel/ValidateTrainingDataViewModel.cs b/NumberRecognizer/NumberRecognizer.App/ViewModel/ValidateTrainingDataViewModel.cs
new file mode 100644
index 0000000..947f9b8
--- /dev/null
+++ b/NumberRecognizer/NumberRecognizer.App/ViewModel/ValidateTrainingDataViewModel.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using GalaSoft.MvvmLight;
+using NumberRecognizer.App.DataModel;
+
+namespace NumberRecognizer.App.ViewModel
+{
+ public class ValidateTrainingDataViewModel : ViewModelBase
+ {
+ private ObservableCollection groups;
+
+ public ValidateTrainingDataViewModel(Dictionary> trainData)
+ {
+ LoadGroups(trainData);
+ }
+
+ private void LoadGroups(Dictionary> trainData)
+ {
+ //Property Changed Raise
+ Groups = new ObservableCollection();
+
+ foreach (int i in trainData.Keys)
+ {
+ var group = new LocalTrainingImageGroup(i.ToString(), i.ToString());
+
+ foreach (LocalTrainingImage image in trainData[i])
+ {
+ group.Items.Add(image);
+ }
+
+ groups.Add(group);
+ }
+ }
+
+ public ObservableCollection Groups
+ {
+ get
+ {
+ return groups;
+ }
+ set
+ {
+ groups = value;
+ RaisePropertyChanged(() => Groups);
+ }
+ }
+
+
+ }
+}