Disable tile in realtime - c#

I am trying to disable a Tile when I start work on Azure.
As you can see, I am using Fody to handle all my PropertyChanged events, but for some reason, it doesn't want to disable and enable again when I am finished.
If you take a look, when I start my work, I put in the explicitly '''IsActive = false'''
UI
<Style x:Key="TileStyle" TargetType="{x:Type mah:Tile}">
<Setter Property="FontWeight" Value="Bold" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Background" Value="{Binding TileColor}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#9A9A9A" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Border Background="#3700b3" CornerRadius="20">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Ellipse
Margin="10"
Fill="Crimson"
HorizontalAlignment="Right"
Width="30" Height="30">
<behaviours:Interaction.Triggers>
<behaviours:EventTrigger EventName="MouseLeftButtonDown">
<behaviours:InvokeCommandAction Command="{Binding ExitCommand}" PassEventArgsToCommand="True"/>
</behaviours:EventTrigger>
</behaviours:Interaction.Triggers>
</Ellipse>
<ItemsControl Grid.Row="1" ItemsSource="{Binding Tiles}" Grid.ColumnSpan="2">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="2" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<mah:Tile
Title="{Binding TileTitle}"
Width="200"
Height="200"
Margin="10"
materialDesign:RippleAssist.RippleOnTop="True"
Command="{Binding TileCommand}"
CommandParameter="{Binding TileIdentifier}"
IsEnabled="{Binding IsTileActive}"
Style="{StaticResource TileStyle}"
TitleFontSize="14">
<Label
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Content="{Binding TileIcon}"
FontFamily="{StaticResource Material}"
FontSize="120"
Foreground="White" />
</mah:Tile>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
And the view Model
[AddINotifyPropertyChangedInterface]
public class MainWindowViewModel {
public Command ExitCommand { get; set; }
public Command AzureCommand { get; set; }
public ObservableCollection<Tile>? Tiles { get; set; }
public List<char> Words { get; set; }
public MainWindowViewModel() {
AzureCommand = new Command(AzureActionAsync);
ExitCommand = new Command(ExiAction);
InitCollection();
Words = new List<char>();
}
private void InitCollection() {
Tiles = new ObservableCollection<Tile>()
{
new Tile(){
IsTileActive = true,
TileTitle = Lang.AudioToText,
TileIdentifier = (int)TilesIdentifiers.Audio,
TileCommand = AzureCommand,
TileIcon = IconFont.VolumeHigh
},
new Tile(){
IsTileActive = true,
TileIdentifier = (int)TilesIdentifiers.Video,
TileTitle = Lang.VideoToText,
TileCommand = AzureCommand,
TileIcon = IconFont.FileVideo
},
new Tile(){
IsTileActive = true,
TileTitle = Lang.ImageToText,
TileIdentifier = (int)TilesIdentifiers.Ocr,
TileCommand = AzureCommand,
TileIcon = IconFont.EyeCircle
},
new Tile(){
IsTileActive = true,
TileTitle = Lang.TranslateDocument,
TileIdentifier = (int)TilesIdentifiers.document,
TileCommand = AzureCommand,
TileIcon = IconFont.FileDocument
},
new Tile(){
IsTileActive = true,
TileIdentifier = (int)TilesIdentifiers.Account,
TileTitle = Lang.Account,
TileCommand = AzureCommand,
TileIcon = IconFont.Account
},
new Tile(){
IsTileActive = true,
TileIdentifier = (int)TilesIdentifiers.About,
TileTitle = Lang.About,
TileCommand = AzureCommand,
TileIcon = IconFont.Help
}
};
}
private void ExiAction() {
Application.Current.Shutdown();
}
private async void AzureActionAsync(object obj) {
OpenFileDialog dlg;
var AudioFolderPath = CreateFolder(ConstantsHelpers.AUDIO);
const string ext = ".wav";
switch (obj) {
case (int)TilesIdentifiers.Audio:
var AudioName = CreateDialog(out dlg, ConstantsHelpers.AUDIO);
var Audiofilename = Path.Combine(AudioFolderPath, $"{AudioName}{ext}");
Converter(dlg, Audiofilename, out _, out _);
await ConvertToTextAsync(Audiofilename);
break;
case (int)TilesIdentifiers.Video:
var VideoName = CreateDialog(out dlg, ConstantsHelpers.VIDEO);
var VideoFilename = Path.Combine(AudioFolderPath, $"{VideoName}{ext}");
var inputFile = new MediaFile { Filename = dlg.FileName };
var outputFile = new MediaFile { Filename = VideoFilename };
var options = new ConversionOptions {
AudioSampleRate = AudioSampleRate.Hz22050
};
var engine = new Engine();
if (!string.IsNullOrEmpty(inputFile.Filename)) {
engine.Convert(inputFile, outputFile, options);
}
break;
case (int)TilesIdentifiers.Ocr:
break;
case (int)TilesIdentifiers.Account:
Debug.WriteLine("Account", "Debug");
break;
case (int)TilesIdentifiers.document:
var storageService = new AzureStorageService();
var DocumentName = CreateDialog(out dlg, ConstantsHelpers.DOCUMENTS);
var path = CreateFolder(ConstantsHelpers.TRANSLATIONS);
if (!string.IsNullOrEmpty(dlg.FileName)) {
var sourceUri = await storageService.UploadToAzureBlobStorage(Path.GetFullPath(dlg.FileName));
var targetUri = await storageService.SaveFromdAzureBlobStorage(Path.GetFullPath(dlg.FileName), path);
await AzureTranslationService.TranslatorAsync(sourceUri, targetUri);
}
break;
case (int)TilesIdentifiers.About:
Debug.WriteLine("about", "Debug");
break;
}
}
private void Converter(OpenFileDialog dlg, string filename, out Mp3FileReader? mp3, out WaveStream? ws) {
if (!string.IsNullOrEmpty(dlg.FileName)) {
mp3 = new Mp3FileReader(dlg.FileName);
ws = WaveFormatConversionStream.CreatePcmStream(mp3);
WaveFileWriter.CreateWaveFile(filename, ws);
} else {
mp3 = null;
ws = null;
return;
}
}
private string? CreateDialog(out OpenFileDialog dlg, string type) {
var filter = string.Empty;
switch (type) {
case ConstantsHelpers.AUDIO:
filter = ConstantsHelpers.AUDIOFILES;
break;
case ConstantsHelpers.VIDEO:
filter = ConstantsHelpers.VIDEOFILES;
break;
case ConstantsHelpers.DOCUMENTS:
filter = ConstantsHelpers.DOCUMENTSFIILES;
break;
case ConstantsHelpers.IMAGES:
filter = ConstantsHelpers.IMAGEFILES;
break;
default:
break;
}
dlg = new OpenFileDialog {
Filter = filter,
};
var res = dlg.ShowDialog();
if (res == true) {
return Path.GetFileNameWithoutExtension(dlg.FileName);
}
return null;
}
private static string CreateFolder(string FolderName = ConstantsHelpers.AUDIO) {
var directoryPath = Directory.CreateDirectory(Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
ConstantsHelpers.TRANSCRIBEME, FolderName));
return directoryPath.FullName;
}
private async Task ConvertToTextAsync(string FilePath) {
//Configure speech service
var config = SpeechConfig.FromSubscription(ConstantsHelpers.AZURE_KEY, ConstantsHelpers.AZURE_REGION);
config.EnableDictation();
//Configure speech recognition
var taskCompleteionSource = new TaskCompletionSource<int>();
using var audioConfig = AudioConfig.FromWavFileInput(FilePath);
using var speechRecognizer = new SpeechRecognizer(config, audioConfig);
speechRecognizer.Recognizing += SpeechRecognizer_Recognizing;
speechRecognizer.Recognized += SpeechRecognizer_Recognized;
speechRecognizer.SessionStarted += SpeechRecognizer_SessionStarted;
speechRecognizer.SessionStopped += SpeechRecognizer_SessionStopped;
await speechRecognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);
Task.WaitAny(new[] { taskCompleteionSource.Task });
await speechRecognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);
}
private void SpeechRecognizer_SessionStopped(object? sender, SessionEventArgs e) {
Tiles![0].IsTileActive = true;
var filename = "Azure.docx";
var pathToSave = CreateFolder(ConstantsHelpers.TRANSCRIPTIONS);
Path.Combine(pathToSave, filename);
var sb = new StringBuilder();
foreach (var item in Words) {
sb.Append(item);
}
using var document = new WordDocument();
document.EnsureMinimal();
document.LastParagraph.AppendText(sb.ToString());
// Find all the text which start with capital letters next to period (.) in the Word document.
//For example . Text or .Text
TextSelection[] textSelections = document.FindAll(new Regex(#"[.]\s+[A-Z]|[.][A-Z]"));
for (int i = 0; i < textSelections.Length; i++) {
WTextRange textToFind = textSelections[i].GetAsOneRange();
//Replace the period (.) with enter(\n).
string replacementText = textToFind.Text.Replace(".", ".\n");
textToFind.Text = replacementText;
}
document.Save(filename);
MessageBox.Show("Created");
}
private void SpeechRecognizer_SessionStarted(object? sender, SessionEventArgs e) {
Tiles![0].IsTileActive = false;
Debug.WriteLine("Started");
}
private void SpeechRecognizer_Recognized(object? sender, SpeechRecognitionEventArgs e) {
if (e.Result.Reason == ResultReason.RecognizedSpeech) {
foreach (var item in e.Result.Text) {
Words.Add(item);
}
}
}
private void SpeechRecognizer_Recognizing(object? sender, SpeechRecognitionEventArgs e) {
When I start the transcription process, my Tile is supposed to be disabled and when I finished enable it, that is why I have `Tle[0]IsTileActive = false when I start working o the transcription process

Related

how can I get external files in C# xamarin forms android?

I'm trying to get images with Xamarin forms Android and I don't know how to do it.
I have a list called listNameImg (I have the name of the each image there). So, what i want is search each image and then save it in a MultipartFormDataContent
This is my code:
MultipartFormDataContent content3 = new MultipartFormDataContent();
private async void takePhotos()
{
try
{
var file2 = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
SaveToAlbum = true
});
while (file2 != null)
{
Image im = new Image();
im.ClassId = contador.ToString();
im.Source = ImageSource.FromFile(file2.Path);
im.HeightRequest = 600;
im.WidthRequest = 600;
im.MinimumHeightRequest = 600;
im.MinimumWidthRequest = 600;
im.VerticalOptions = LayoutOptions.End;
im.HorizontalOptions = LayoutOptions.End;
im.Aspect = Aspect.AspectFill;
imgs.Children.Add(im);
Button deleteButton = new Button();
deleteButton.ClassId = contador.ToString();
deleteButton.Text = "Borrar imagen";
deleteButton.VerticalOptions = LayoutOptions.CenterAndExpand;
deleteButton.HorizontalOptions = LayoutOptions.Center;
deleteButton.MinimumWidthRequest = 100;
deleteButton.ClassId = contador.ToString();
deleteButton.AutomationId = contador.ToString();
deleteButton.Clicked += async (sender, args) => {
listDelete.Add(Convert.ToInt32(deleteButton.ClassId));
imgs.Children.Remove(im);
imgs.Children.Remove(deleteButton);
};
imgs.Children.Add(deleteButton);
listImgName.Add(file2.OriginalFilename);
file2 = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
SaveToAlbum = true
});
contador++;
}
btnScannerQR.IsVisible = false;
btnSacarFotos.IsVisible = true;
btnEnviarImagenes.IsVisible = true;
}
catch(Exception ex)
{
await DisplayAlert("Error", "Sorry we had a problem. Try again.", "OK");
await Shell.Current.GoToAsync($"//{nameof(HomePage)}");
}
private async void storageNameInList() {
string testPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), "listNameImg.txt");
if (File.Exists(testPath) == false)
{
File.Create(testPath);
}
TextWriter tw = new StreamWriter(testPath);
foreach (var s in listImgName)
{
tw.WriteLine(s);
}
tw.Close();
}
what I'm trying:
private async void sendImages(){
string testPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), "listNameImg.txt");
var imgGroup = Directory.GetFiles(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyPictures));
TextReader tw = new StreamReader(testPath);
String line;
int cont = 0;
while ((line = tw.ReadLine()) != null)
{
byte[] byteArray = Encoding.UTF8.GetBytes(line);
content3.Add(new StreamContent(File.OpenRead(line)), "file", line);
cont++;
}
}
My problems are:
how can I write in the file .txt correctly?
how can I get the images and save it in the MultipartFormDataContent?
Thank you very much!

Lazy Loading gridview from json

I have a lazy loading in gridview whose data is taken from JSON.
Sample of JSON:
{
"error": false,
"total_data": 32,
"data_per_page": "16",
"current_page": 1,
"total_page": 2,
"current_total": 16,
"data": [
{
"id": "2613",
"judul": "Kamus ID EN",
"slug": "kamus-id-en",
"cover": "https://mhnkp2.com/src/umum/cover/kamus_ID_EN-thumb.jpg",
"path": "https://mhnkp2.com/school/dl/dodl/2613",
"ukuran": "3504835",
"formated_size": "3.34 MB",
"fname": "kamus_ID_EN.pdf",
"publish": "1",
"urgent": "400",
"kelas": "0",
"nama_kelas": "Umum"
},
XAML:
<Grid x:Name="content" Grid.Row="1" Loaded="MainGrid_Loaded">
<GridView
x:Name="itemGridView"
Loaded="itemGridView_Loaded">
<GridView.ItemTemplate>
<DataTemplate>
<Grid
Width="135"
Height="280"
Margin="5,5,5,5"
Background="White">
<TextBlock
x:Name="title"
Margin="0,0,10,10"
FontSize="14"
FontWeight="SemiBold"
Foreground="Black"
Style="{StaticResource TitleTextBlockStyle}"
Text="{Binding Judul}"
TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
Code:
ObservableCollection<Buku> datasource = new ObservableCollection<Buku>();
int offset = 0;
private void MainGrid_Loaded(object sender, RoutedEventArgs e)
{
itemGridView.ItemsSource = datasource;
Umum(1);
}
public class Buku
{
public string Judul { get; set; }
}
private async void Umum(int offset)
{
urlPath = "https://mhnkp2.com/school/api-v3/fetch/umum";
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("halaman", offset.ToString()),
new KeyValuePair<string, string>("limit", "16"),
new KeyValuePair<string, string>("SCH-API-KEY", "SCH_KEnaBiDeplebt")
};
var response = await httpClient.PostAsync(urlPath, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
string jsonText = await response.Content.ReadAsStringAsync();
try
{
double total = groupObject1["total_data"].GetNumber();
double pages = groupObject1["total_page"].GetNumber();
double page = groupObject1["current_page"].GetNumber();
Buku file = new Buku();
file.PageNo = Convert.ToInt32(page);
file.Pages = Convert.ToInt32(pages);
file.Total = Convert.ToInt32(total);
JsonArray jsonData1 = jsonObject["data"].GetArray();
foreach (JsonValue groupValue1 in jsonData1)
{
JsonObject groupObject2 = groupValue1.GetObject();
string title = groupObject2["judul"].GetString();
Buku file1 = new Buku();
file1.Judul = title;
datasource.Add(file1);
}
itemGridView.ItemsSource = datasource;
}
}
private void itemGridView_Loaded(object sender, RoutedEventArgs e)
{
ScrollViewer viewer = GetScrollViewer(this.itemGridView);
viewer.ViewChanged += Viewer_ViewChanged;
}
private void Viewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
ScrollViewer view = (ScrollViewer)sender;
double progress = view.VerticalOffset / view.ScrollableHeight;
//Debug.WriteLine(progress);
if (progress > 0.7 && !incall && !endoflist)
{
incall = true;
busyindicator.IsActive = true;
Umum(++offset);
}
}
public static ScrollViewer GetScrollViewer(DependencyObject depObj)
{
if (depObj is ScrollViewer) return depObj as ScrollViewer;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = GetScrollViewer(child);
if (result != null) return result;
}
return null;
}
I am having a problem, that the gridview should display data on pages 1 and 2, but in the gridview the data displayed on page 2 is a repetition of data on page 1, as shown below:
How to fix it?
Note:
The page uses the "offset" parameter
The page limit is "total_page" in JSON
you just need to pass the offset value to MainGrid_Loaded and set offset zero to one
ObservableCollection<Buku> datasource = new ObservableCollection<Buku>();
int offset = 1; // set offset zero to one
private void MainGrid_Loaded(object sender, RoutedEventArgs e)
{
itemGridView.ItemsSource = datasource;
Umum(offset); // just change 1 to offset
}
public class Buku
{
public string Judul { get; set; }
}
private async void Umum(int offset)
{
urlPath = "mhnkp2.com/school/api-v3/fetch/ktsp2006/kelas/1";
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("halaman", offset.ToString()),
new KeyValuePair<string, string>("limit", "16"),
new KeyValuePair<string, string>("SCH-API-KEY", "SCH_KEnaBiDeplebt")
};
var response = await httpClient.PostAsync(urlPath, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
string jsonText = await response.Content.ReadAsStringAsync();
try
{
double total = groupObject1["total_data"].GetNumber();
double pages = groupObject1["total_page"].GetNumber();
double page = groupObject1["current_page"].GetNumber();
Buku file = new Buku();
file.PageNo = Convert.ToInt32(page);
file.Pages = Convert.ToInt32(pages);
file.Total = Convert.ToInt32(total);
JsonArray jsonData1 = jsonObject["data"].GetArray();
foreach (JsonValue groupValue1 in jsonData1)
{
JsonObject groupObject2 = groupValue1.GetObject();
string title = groupObject2["judul"].GetString();
Buku file1 = new Buku();
file1.Judul = title;
datasource.Add(file1);
}
itemGridView.ItemsSource = datasource;
}
}
private void itemGridView_Loaded(object sender, RoutedEventArgs e)
{
ScrollViewer viewer = GetScrollViewer(this.itemGridView);
viewer.ViewChanged += Viewer_ViewChanged;
}
private void Viewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
ScrollViewer view = (ScrollViewer)sender;
double progress = view.VerticalOffset / view.ScrollableHeight;
//Debug.WriteLine(progress);
if (progress > 0.7 && !incall && !endoflist)
{
incall = true;
busyindicator.IsActive = true;
Umum(offset++);
}
}
public static ScrollViewer GetScrollViewer(DependencyObject depObj)
{
if (depObj is ScrollViewer) return depObj as ScrollViewer;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = GetScrollViewer(child);
if (result != null) return result;
}
return null;
}

C# Event fires a lot of times

I have a problem. I am using a CollectionView that receives data in a custom ViewModel from my webpage as long as it returns a JSON with the data. Once the Offset in the call >= num_of_rows the webpage prints "Nothing". If that happens I set a boolean HitBottomOfList = true;. Now everytime when it wants to do a webcall it checks if the HitBottomOfList == false.
Full Code
ViewModel:
public class TemplateListViewModel
{
public double WidthHeight { get; set; }
public ICommand LoadTemplates => new Command(LoadTemplateList);
public int CurrentTemplateCountReceived;
public bool HitBottomOfList = false;
public ObservableCollection<TemplateSource> sourceList { get; set; }
public TemplateListViewModel()
{
CurrentTemplateCountReceived = 0;
sourceList = new ObservableCollection<TemplateSource>();
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
var width = mainDisplayInfo.Width;
var density = mainDisplayInfo.Density;
var ScaledWidth = width / density;
WidthHeight = (ScaledWidth / 2);
loadingTemplates += onLoadingTemplates;
LoadTemplateList();
}
private event EventHandler loadingTemplates = delegate { };
private void LoadTemplateList()
{
loadingTemplates(this, EventArgs.Empty);
}
private async void onLoadingTemplates(object sender, EventArgs args)
{
if (HitBottomOfList == false)
{
List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived);
if (templateList != null)
{
foreach (var template in templateList)
{
ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName));
TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight = WidthHeight, FileName = template.FileName };
sourceList.Add(templateSource);
}
CurrentTemplateCountReceived = sourceList.Count;
}
else
{
HitBottomOfList = true;
}
}
}
}
The XAML:
<CollectionView ItemsSource="{Binding sourceList}" RemainingItemsThreshold="6"
RemainingItemsThresholdReachedCommand="{Binding LoadTemplates}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ff:CachedImage
Source="{Binding Source}"
VerticalOptions="Center"
HorizontalOptions="Center"
WidthRequest="{Binding WidthHeight}"
HeightRequest="{Binding WidthHeight}">
<ff:CachedImage.GestureRecognizers>
<TapGestureRecognizer Tapped="imgTemplate_Clicked" />
</ff:CachedImage.GestureRecognizers>
</ff:CachedImage>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
And finally the WebCall that I do:
public async Task<List<Template>> GetTemplates(User user, int offset)
{
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("un", user.Username));
postData.Add(new KeyValuePair<string, string>("pw", user.Password));
postData.Add(new KeyValuePair<string, string>("offset", offset.ToString()));
var content = new FormUrlEncodedContent(postData);
var weburl = "mysite.org/myapp/get_templates.php";
List<Template> response = await PostResponseTemplates(weburl, content);
return response;
}
public async Task<List<Template>> PostResponseTemplates(string weburl, FormUrlEncodedContent content)
{
var response = await client.PostAsync(weburl, content);
var json = await response.Content.ReadAsStringAsync();
if (json != "Nothing")
{
var jObject = JObject.Parse(json);
var templatePropery = jObject["Templates"] as JArray;
List<Template> templateList = new List<Template>();
foreach (var property in templatePropery)
{
List<Template> propertyList = new List<Template>();
propertyList = JsonConvert.DeserializeObject<List<Template>>(property.ToString());
templateList.AddRange(propertyList);
}
var sourcePropery = (JObject)jObject["Source"];
foreach (var property in sourcePropery)
{
string tempplateSource = property.Value.Value<string>();
App.TemplateSource = tempplateSource;
}
return templateList;
}
else
{
ErrorMessage = json;
return default(List<Template>);
}
}
Now the problem is that when it does trigger the RemainingItemsThresholdReachedCommand="{Binding LoadTemplates}"
it executes the command a lot of times after each other, thinking it needs more data, while there is already a command to get new data. This causes the app to get new data with the same offset a few times, so the app will the same data in the CollectionView a lot of times.
I want the app to call the webpage 1 time to receive more images and just let it load, without asking again for new data, so the duplicates in the list will disappear.
So how can I make sure it only asks the data once, when almost hit the bottom?
Update
Using #Jason his code the following is going wrong:
When the code goes through the MyHandler, it fires the LoadTemplateList(); But jumps to the handling = false; before it finished, so the next command is allowed to start, without finishing the other. Any idea how to wait for the method to finish?
use a bool to track if you are already handling the event and ignore any new ones
bool handling = false;
public void MyHandler()
{
// already handling an event, ignore the new one
if (handling) return;
handling = true;
// process event here
handling = false;
}

System.OutOfMemoryExeption C#

When I'm running my application and load a file(25MB) through it, everything runs just fine.
But when I try loading a file(160MB) I get a System.OutOfMemoryExeption.
Although I have been able to load the larger file at some point in time.
Is there anyway to fix this? If so, any help would be much appreciated!
My Code that loads the files:
private void openFile (string fileName)
{
List<Structs.strValidData> _header1 = new List<Structs.strValidData>();
List<Structs.strValidData> _header2 = new List<Structs.strValidData>();
List<Structs.strValidData> _header3 = new List<Structs.strValidData>();
List<Structs.strValidData> _header4 = new List<Structs.strValidData>();
var textBoxArray = new[]
{
textBoxResStart_Status1,
textBoxResStart_Status2,
textBoxResStart_Status3,
textBoxResStart_Status4,
textBoxResStart_Status5,
textBoxResStart_Status6,
textBoxResStart_Status7,
textBoxResStart_Status8,
};
var radioButtonArray = new[]
{
radioButtonResStart_SelectStr1,
radioButtonResStart_SelectStr2,
radioButtonResStart_SelectStr3,
radioButtonResStart_SelectStr4,
radioButtonResStart_SelectStr5,
radioButtonResStart_SelectStr6,
radioButtonResStart_SelectStr7,
radioButtonResStart_SelectStr8,
};
readCSV read;
read = new readCSV();
strInfo = default(Structs.strInfo);
strData = default(Structs.strData);
strSetup = default(Structs.strSetup);
strValidData = new List<Structs.strValidData>();
readID = default(Structs.ReadID);
try
{
strInfo = read.loadInfo(fileName);
strData = read.loadData(fileName);
strSetup = read.loadSetup(fileName);
readID = read.loadID(fileName);
strValidData = read.loadValidData(fileName);
var Str1 = read.loadStr1(fileName);
var Str235678 = read.loadStr235678(fileName);
var Str4 = read.loadStr4(fileName);
foreach (Structs.strValidData items in strValidData)
{
if (items.Str1_ValidData == true)
{
Str1_headers.Add(items);
}
if (items.Str2_ValidData == true ||
items.Str3_ValidData == true ||
items.Str5_ValidData == true ||
items.Str6_ValidData == true ||
items.Str7_ValidData == true ||
items.Str8_ValidData == true)
{
Str235678_headers.Add(items);
}
if (items.Str4_ValidData == true)
{
Str4_headers.Add(items);
}
}
Str1_data = combineData(Str1, Str1_headers);
Str4_data = combineData(Str4, Str4_headers);
var Str235678_CombinedData = combineData(Str235678, Str235678_headers);
foreach (Structs.strValidData items in Str235678_CombinedData)
{
if (items.Str2_ValidData == true)
{
Str2_data.Add(items);
}
if (items.Str3_ValidData == true)
{
Str3_data.Add(items);
}
if (items.Str5_ValidData == true)
{
Str5_data.Add(items);
}
if (items.Str6_ValidData == true)
{
Str6_data.Add(items);
}
if (items.Str7_ValidData == true)
{
Str7_data.Add(items);
}
if (items.Str8_ValidData == true)
{
Str8_data.Add(items);
}
}
strInfo = read.loadInfo(openDialog.FileName);
strData = read.loadData(openDialog.FileName);
strSetup = read.loadSetup(openDialog.FileName);
readID = read.loadID(openDialog.FileName);
}
catch (Exception err)
{
MessageBox.Show(err.Message);
error.logSystemError(err);
}
}
Here are the ReadCSV() code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using FileHelpers;
using FileHelpers.Events;
namespace Reading_Files
{
public class readCSV
{
public int strCnt = 0;
private readCSVprogressForm _waitForm;
public List<Structs.strDataImport> copyList(List<strData> copyFrom)
{
List<Structs.strDataImport> list = new List<Structs.strDataImport>();
list.AddRange(copyFrom.Select(s => copyListContents(s)));
return list;
}
public Structs.strDataImport copyListContents(strData copyFrom)
{
Structs.strDataImport data = new Structs.strDataImport();
data.sCD_TimeCP2711 = copyFrom.sCD_TimeCP2711;
data.sCD_TimeCX9020_1 = copyFrom.sCD_TimeCX9020_1;
data.sCD_TimeCX9020_2 = copyFrom.sCD_TimeCX9020_2;
data.rCD_CX9020_1_TimeDiff_DataLow = (Int32)(copyFrom.rCD_CX9020_1_TimeDiff_DataLow);
data.rCD_CX9020_2_TimeDiff_DataLow = (Int32)(copyFrom.rCD_CX9020_2_TimeDiff_DataLow);
data.iCD_NumUpper = copyFrom.iCD_NumUpper;
data.iCD_NumUpper = copyFrom.iCD_NumUpper;
data.iCD_NumLower = copyFrom.iCD_NumLower;
data.iCD_NumLower = copyFrom.iCD_NumLower;
data.bCD_1_Status = copyFrom.bCD_1_Status;
data.bCD_1_Overrange = copyFrom.bCD_1_Overrange;
data.iCD_1_Str_ID = copyFrom.iCD_1_Str_ID;
data.rCD_1_Value = copyFrom.rCD_1_Value;
data.bCD_2_Status = copyFrom.bCD_2_Status;
data.bCD_2_Overrange = copyFrom.bCD_2_Overrange;
data.iCD_2_Str_ID = copyFrom.iCD_2_Str_ID;
data.rCD_2_Value = copyFrom.rCD_2_Value;
data.bCD_3_Status = copyFrom.bCD_3_Status;
data.bCD_3_Overrange = copyFrom.bCD_3_Overrange;
data.iCD_3_Str_ID = copyFrom.iCD_3_Str_ID;
data.iCD_3_RawData = copyFrom.iCD_3_RawData;
data.rCD_3_Value = copyFrom.rCD_3_Value;
data.bCD_4_Status = copyFrom.bCD_4_Status;
data.bCD_4_Overrange = copyFrom.bCD_4_Overrange;
data.iCD_4_Str_ID = copyFrom.iCD_4_Str_ID;
data.iCD_4_RawData = copyFrom.iCD_4_RawData;
data.rCD_4_Value = copyFrom.rCD_4_Value;
data.bCD_5_Status = copyFrom.bCD_5_Status;
data.bCD_5_Overrange = copyFrom.bCD_5_Overrange;
data.iCD_5_Str_ID = copyFrom.iCD_5_Str_ID;
data.iCD_5_RawData = copyFrom.iCD_5_RawData;
data.rCD_5_Value = copyFrom.rCD_5_Value;
data.bCD_6_Status = copyFrom.bCD_6_Status;
data.bCD_6_Overrange = copyFrom.bCD_6_Overrange;
data.iCD_6_Str_ID = copyFrom.iCD_6_Str_ID;
data.iCD_6_RawData = copyFrom.iCD_6_RawData;
data.rCD_6_Value = copyFrom.rCD_6_Value;
data.bCD_7_Status = copyFrom.bCD_7_Status;
data.bCD_7_Overrange = copyFrom.bCD_7_Overrange;
data.iCD_7_Str_ID = copyFrom.iCD_7_Str_ID;
data.iCD_7_RawData = copyFrom.iCD_7_RawData;
data.rCD_7_Value = copyFrom.rCD_7_Value;
data.bCD_8_Status = copyFrom.bCD_8_Status;
data.bCD_8_Overrange = copyFrom.bCD_8_Overrange;
data.iCD_8_Str_ID = copyFrom.iCD_8_Str_ID;
data.iCD_8_RawData = copyFrom.iCD_8_RawData;
data.rCD_8_Value = copyFrom.rCD_8_Value;
data.bCD_9_Status = copyFrom.bCD_9_Status;
data.bCD_9_Overrange = copyFrom.bCD_9_Overrange;
data.iCD_9_Str_ID = copyFrom.iCD_9_Str_ID;
data.iCD_9_RawData = copyFrom.iCD_9_RawData;
data.rCD_9_Value = copyFrom.rCD_9_Value;
data.bCD_10_Status = copyFrom.bCD_10_Status;
data.bCD_10_Overrange = copyFrom.bCD_10_Overrange;
data.iCD_10_Str_ID = copyFrom.iCD_10_Str_ID;
data.iCD_10_RawData = copyFrom.iCD_10_RawData;
data.rCD_10_Value = copyFrom.rCD_10_Value;
data.bCD_11_Status = copyFrom.bCD_11_Status;
data.bCD_11_Overrange = copyFrom.bCD_11_Overrange;
data.iCD_11_Str_ID = copyFrom.iCD_11_Str_ID;
data.iCD_11_RawData = copyFrom.iCD_11_RawData;
data.rCD_11_Value = copyFrom.rCD_11_Value;
data.bCD_12_Status = copyFrom.bCD_12_Status;
data.bCD_12_Overrange = copyFrom.bCD_12_Overrange;
data.iCD_12_Str_ID = copyFrom.iCD_12_Str_ID;
data.iCD_12_RawData = copyFrom.iCD_12_RawData;
data.rCD_12_Value = copyFrom.rCD_12_Value;
data.bCD_13_Status = copyFrom.bCD_13_Status;
data.bCD_13_Overrange = copyFrom.bCD_13_Overrange;
data.iCD_13_Str_ID = copyFrom.iCD_13_Str_ID;
data.iCD_13_RawData = copyFrom.iCD_13_RawData;
data.rCD_13_Value = copyFrom.rCD_13_Value;
data.bCD_14_Status = copyFrom.bCD_14_Status;
data.bCD_14_Overrange = copyFrom.bCD_14_Overrange;
data.iCD_14_Str_ID = copyFrom.iCD_14_Str_ID;
data.iCD_14_RawData = copyFrom.iCD_14_RawData;
data.rCD_14_Value = copyFrom.rCD_14_Value;
data.bCD_15_Status = copyFrom.bCD_15_Status;
data.bCD_15_Overrange = copyFrom.bCD_15_Overrange;
data.iCD_15_Str_ID = copyFrom.iCD_15_Str_ID;
data.iCD_15_RawData = copyFrom.iCD_15_RawData;
data.rCD_15_Value = copyFrom.rCD_15_Value;
data.bCD_16_Status = copyFrom.bCD_16_Status;
data.bCD_16_Overrange = copyFrom.bCD_16_Overrange;
data.iCD_16_Str_ID = copyFrom.iCD_16_Str_ID;
data.iCD_16_RawData = copyFrom.iCD_16_RawData;
data.rCD_16_Value = copyFrom.rCD_16_Value;
data.bCD_17_Status = copyFrom.bCD_17_Status;
data.bCD_17_Overrange = copyFrom.bCD_17_Overrange;
data.iCD_17_Str_ID = copyFrom.iCD_17_Str_ID;
data.iCD_17_RawData = copyFrom.iCD_17_RawData;
data.rCD_17_Value = copyFrom.rCD_17_Value;
data.bCD_18_Status = copyFrom.bCD_18_Status;
data.bCD_18_Overrange = copyFrom.bCD_18_Overrange;
data.iCD_18_Str_ID = copyFrom.iCD_18_Str_ID;
data.iCD_18_RawData = copyFrom.iCD_18_RawData;
data.rCD_18_Value = copyFrom.rCD_18_Value;
data.bCD_19_Status = copyFrom.bCD_19_Status;
data.bCD_19_Overrange = copyFrom.bCD_19_Overrange;
data.iCD_19_Str_ID = copyFrom.iCD_19_Str_ID;
data.rCD_19_Value = copyFrom.rCD_19_Value;
data.bCD_20_Status = copyFrom.bCD_20_Status;
data.bCD_20_Overrange = copyFrom.bCD_20_Overrange;
data.iCD_20_Str_ID = copyFrom.iCD_20_Str_ID;
data.rCD_20_Value = copyFrom.rCD_20_Value;
return data;
}
public Structs.ReaStrID load_ID(string FileName)
{
var engine = new MultiRecordEngine(typeof(strInfo),
typeof(strData),
typeof(strSetup),
typeof(strID),
typeof(strData));
engine.RecordSelector = new RecordTypeSelector(strIDSelector);
var data = engine.ReadFile(FileName);
Structs.ReaStrID structure = new Structs.ReaStrID();
foreach (strID filteredData in data)
{
structure.steID[0] = filteredData._1_Ste_ID;
structure.Status[0] = filteredData._1_Status;
structure.steID[1] = filteredData._2_Ste_ID;
structure.Status[1] = filteredData._2_Status;
structure.steID[2] = filteredData._3_Ste_ID;
structure.Status[2] = filteredData._3_Status;
structure.steID[3] = filteredData._4_Ste_ID;
structure.Status[3] = filteredData._4_Status;
structure.steID[4] = filteredData._5_Ste_ID;
structure.Status[4] = filteredData._5_Status;
}
return structure;
}
public Structs.strInfo loadInfo(string FileName)
{
var engine = new MultiRecordEngine(typeof(strInfo),
typeof(strData),
typeof(strSetup),
typeof(strID),
typeof(strData));
engine.RecordSelector = new RecordTypeSelector(strInfoSelector);
var data = engine.ReadFile(FileName);
Structs.strInfo structure = new Structs.strInfo();
foreach (strInfo filteredData in data)
{
structure.Date = filteredData.Date;
structure.Description1 = filteredData.Description1;
structure.Description2 = filteredData.Description2;
structure.Description3 = filteredData.Description3;
}
return structure;
}
public Structs.strData loadData(string FileName)
{
var engine = new MultiRecordEngine(typeof(strInfo),
typeof(strData),
typeof(strSetup),
typeof(strID),
typeof(strData));
engine.RecordSelector = new RecordTypeSelector(strDataSelector);
var data = engine.ReadFile(FileName);
Structs.strData structure = new Structs.strData();
foreach (strData filteredData in data)
{
structure.iMDstr_var1_TypeID = filteredData.iMDstr_var1_TypeID;
structure.rMDstr_var1_Lenght = filteredData.rMDstr_var1_Lenght;
structure.iMDstr_var2_TypeID = filteredData.iMDstr_var2_TypeID;
structure.rMDstr_var2_Lenght = filteredData.rMDstr_var2_Lenght;
structure.iMDstr_var3_TypeID = filteredData.iMDstr_var3_TypeID;
structure.rMDstr_var3_Lenght = filteredData.rMDstr_var3_Lenght;
structure.iMDstr_var4_TypeID = filteredData.iMDstr_var4_TypeID;
structure.rMDstr_var4_Lenght = filteredData.rMDstr_var4_Lenght;
}
return structure;
}
public Structs.strSetup loadSetup(string FileName)
{
var engine = new MultiRecordEngine(typeof(strInfo),
typeof(strID),
typeof(strData),
typeof(strSetup),
typeof(strData));
engine.RecordSelector = new RecordTypeSelector(strSetupSelector);
var data = engine.ReadFile(FileName);
Structs.strSetup structure = new Structs.strSetup();
foreach (strSetup filteredData in data)
{
structure.sSSstr_Sens = filteredData.sSSstr_Sens;
structure.bSSstr_S1_A = filteredData.bSSstr_S1_A;
structure.iSSstr_S1_B = filteredData.iSSstr_S1_B;
structure.sSSstr_S1_C = filteredData.sSSstr_S1_C;
structure.rSSstr_S1_D = filteredData.rSSstr_S1_D;
structure.bSSstr_S2_A = filteredData.bSSstr_S2_A;
structure.iSSstr_S2_B = filteredData.iSSstr_S2_B;
structure.sSSstr_S2_C = filteredData.sSSstr_S2_C;
structure.rSSstr_S2_D = filteredData.rSSstr_S2_D;
structure.bSSstr_S3_A = filteredData.bSSstr_S3_A;
structure.iSSstr_S3_B = filteredData.iSSstr_S3_B;
structure.sSSstr_S3_C = filteredData.sSSstr_S3_C;
structure.iSSstr_S3_D = filteredData.iSSstr_S3_D;
}
return structure;
}
public List<Structs.str1> load1(string FileName)
{
var engine = new MultiRecordEngine(typeof(strInfo),
typeof(strData),
typeof(strSetup),
typeof(strData),
typeof(strID),
typeof(strValidData),
typeof(strStartNum),
typeof(str1),
typeof(str4));
engine.RecordSelector = new RecordTypeSelector(str1Selector);
var data = engine.ReadFile(FileName);
List<Structs.str1> list = new List<Structs.str1>();
int i = 0;
foreach (str1 data1 in data)
{
Structs.str1 structure = new Structs.str1();
structure.rGL_1_L_Positive = data1.rGL_1_L_Positive;
structure.rGL_1_L_Negative = data1.rGL_1_L_Negative;
structure.rGL_1_R_Positive = data1.rGL_1_R_Positive;
structure.rGL_1_R_Negative = data1.rGL_1_R_Negative;
list.Add(structure);
i++;
}
return list;
}
public List<Structs.str4> load4(string FileName)
{
var engine = new MultiRecordEngine(typeof(strInfo),
typeof(strData),
typeof(strSetup),
typeof(strData),
typeof(strValidData),
typeof(strStartNum),
typeof(str1),
typeof(str4));
engine.RecordSelector = new RecordTypeSelector(str4Selector);
var data = engine.ReadFile(FileName);
List<Structs.str4> list = new List<Structs.str4>();
int i = 0;
foreach (str4 data4 in data)
{
Structs.str4 structure = new Structs.str4();
structure.rGL_4_1 = data4.rGL_4_1;
structure.rGL_4_2 = data4.rGL_4_2;
structure.rGL_4_3 = data4.rGL_4_3;
structure.rGL_4_4 = data4.rGL_4_4;
structure.rGL_4_5 = data4.rGL_4_5;
structure.rGL_4_6 = data4.rGL_4_6;
structure.rGL_4_7 = data4.rGL_4_7;
structure.rGL_4_8 = data4.rGL_4_8;
list.Add(structure);
i++;
}
return list;
}
public List<Structs.strValidData> loadValidData(string FileName)
{
var engine = new MultiRecordEngine(typeof(strInfo),
typeof(strData),
typeof(strSetup),
typeof(strID),
typeof(strData),
typeof(strValidData));
engine.RecordSelector = new RecordTypeSelector(strValidDataSelector);
var data = engine.ReadFile(FileName);
List<Structs.strValidData> list = new List<Structs.strValidData>();
int i = 0;
foreach (strValidData strValidData in data)
{
Structs.strValidData structure = new Structs.strValidData();
structure._name = String.Format("strItem {0}", i + 1);
structure._index = i;
structure.str1_ValidData = strValidData.str1_ValidData;
structure.str2_ValidData = strValidData.str2_ValidData;
structure.str3_ValidData = strValidData.str3_ValidData;
structure.str4_ValidData = strValidData.str4_ValidData;
structure.str5_ValidData = strValidData.str5_ValidData;
structure.str6_ValidData = strValidData.str6_ValidData;
structure.str7_ValidData = strValidData.str7_ValidData;
structure.str8_ValidData = strValidData.str8_ValidData;
structure.str9_ValidData = strValidData.str9_ValidData;
list.Add(structure);
i++;
}
return list;
}
public List<List<Structs.strDataImport>> loadstrDataAsync(string FileName)
{
var engine_Data = new FileHelperAsyncEngine<strData>();
engine_Data.BeforeReadRecord += BeforeEventAsync;
engine_Data.AfterReadRecord += AfterEventAsync;
engine_Data.Progress += ReadProgress;
List<strData> list = new List<strData>();
List<List<Structs.strDataImport>> list2D = new List<List<Structs.strDataImport>>();
using (engine_Data.BeginReadFile(FileName))
{
var prevRowNo = 0;
var j = 0;
strCnt = 0;
foreach (strData filteredData in engine_Data)
{
if (prevRowNo > filteredData.RowNo)
{
list2D.Add(copyList(list));
list.Clear();
}
prevRowNo = filteredData.RowNo;
list.Add(filteredData);
}
list2D.Add(copyList(list));
}
return list2D;
}
private Type strIDSelector(MultiRecordEngine engine, string recordLine)
{
if (recordLine.Length == 0)
return null;
if (recordLine.Contains("** #_DATA .STATUS .STRID **"))
return typeof(strID);
else
{
return null;
}
}
private Type InfoSelector(MultiRecordEngine engine, string recordLine)
{
if (recordLine.Length == 0)
return null;
if (recordLine.Contains("** #_FILE **"))
return typeof(strInfo);
else
{
return null;
}
}
private Type strDataSelector(MultiRecordEngine engine, string recordLine)
{
if (recordLine.Length == 0)
return null;
if (recordLine.Contains("** #_DATA **"))
return typeof(strData);
else
{
return null;
}
}
private Type strSetupSelector(MultiRecordEngine engine, string recordLine)
{
if (recordLine.Length == 0)
return null;
if (recordLine.Contains("** #_SETUP **"))
return typeof(strSetup);
else
{
return null;
}
}
private Type strValidDataSelector(MultiRecordEngine engine, string recordLine)
{
if (recordLine.Length == 0)
return null;
if (recordLine.Contains("** #_VALID_DATA **"))
return typeof(strValidData);
else
{
return null;
}
}
private Type StartNumSelector(MultiRecordEngine engine, string recordLine)
{
if (recordLine.Length == 0)
return null;
if (recordLine.Contains("** #_START_NUMBER **"))
return typeof(strStartNum);
else
{
return null;
}
}
private Type str1Selector(MultiRecordEngine engine, string recordLine)
{
if (recordLine.Length == 0)
return null;
if (recordLine.Contains("** #_1 **"))
return typeof(str1);
else
{
return null;
}
}
private Type str4Selector(MultiRecordEngine engine, string recordLine)
{
if (recordLine.Length == 0)
return null;
if (recordLine.Contains("** #_4 **"))
return typeof(str4);
else
{
return null;
}
}
private void BeforeEventAsync(EngineBase engine, BeforeReadEventArgs<strData> e)
{
if (e.RecordLine != "")
{
if (Char.IsDigit(e.RecordLine, 0))
{
}
else
{
e.SkipThisRecord = true;
}
}
if (e.RecordLine.Contains("** #_VALID_DATA **;"))
{
e.SkipThisRecord = true;
}
}
private void AfterEventAsync(EngineBase engine, AfterReadEventArgs<strData> e)
{
if (e.RecordLine.Contains("** #_VALID_DATA **;"))
{
e.SkipThisRecord = true;
}
}
private void ReadProgress(object sender, ProgressEventArgs e)
{
ShowWaitForm("Opening file." + "\n" + "\n" + "Please wait...", "Open File");
_waitForm.progressBar1.Value = Convert.ToInt16(e.Percent);
}
public void ShowWaitForm(string message, string caption)
{
if (_waitForm != null && !_waitForm.IsDisposed)
{
return;
}
_waitForm = new readCSVprogressForm();
_waitForm.ShowMessage(message);
_waitForm.Text = caption;
_waitForm.TopMost = true;
_waitForm.Show();
_waitForm.Refresh();
System.Threading.Thread.Sleep(700);
Application.Idle += OnLoaded;
}
private void OnLoaded(object sender, EventArgs e)
{
Application.Idle -= OnLoaded;
_waitForm.Close();
}
}
}
Given the comments, it sounds like the problem is really that you're using structs extensively. These should almost certainly be classes for idiomatic C#. See the design guidelines for more details of how to pick between these.
At the moment, you're loading all the values in a big List<T>. Internally, that has an array - so it's going to be an array of your struct type. That means all the values are required to be in a single contiguous chunk of memory - and it sounds like that chunk can't be allocated.
If you change your data types to classes, then a contiguous chunk of memory will still be required - but only enough to store references to the objects you create. You'll end up using slightly more data overall (due to per-object overhead and the references to those objects) but you won't have nearly as strict a requirement on allocating a single big chunk of memory.
That's only one reason to use classes here - the reason of "this just isn't a normal use of structs" is a far bigger one, IMO.
As an aside, I'd also very strongly recommend that you start following .NET naming conventions, particularly around the use of capitalization and avoiding underscores to separate words in names. (There are other suggestions for improving the code in the question too, and I'd advise reading them all carefully.)

Temporarily Sort WP8 Listbox

I have an WP C# app built on the Local Database Sample (http://code.msdn.microsoft.com/wpapps/Local-Database-Sample-57b1614c).
The main page displays a list of items from the xml database, which by default shows items in the order created. I would like to be able to offer at least one other sort order - either reversed or sorted by "Subject". Unfortunately Listbox.Sort is not supported in WP.
I have tried various answers found on here, including attempting to sort the xml file itself, but for reasons beyond my level of coding they do not change the order of the list (see Templatestorage) however i suspect it is due to improper implementation.
The code for the listbox is:
<ListBox x:Name="Templates" SelectionChanged="OnSelectionChanged" Background="Transparent" Style="{StaticResource ListBoxStyle1}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Grid.Row="2" Text="{Binding Subject}" Style="{StaticResource PhoneTextLargeStyle}" Margin="12,2" />
<TextBlock Grid.Row="2" Text="{Binding DT}" Style="{StaticResource PhoneTextSmallStyle}" Margin="12,5" />
<Rectangle Height="1" Margin="23,7,50,7" Fill="{StaticResource PhoneAccentBrush}" MinWidth="400" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The c# is:
public partial class MainPage
{
private readonly TemplateStorage storage = new TemplateStorage();
public MainPage()
{
InitializeComponent();
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
Templates.ItemsSource = storage.GetItems();
this.NavigationService.RemoveBackEntry();
}
private void PhoneApplicationPage_GotFocus(object sender, RoutedEventArgs e)
{
Templates.ItemsSource = storage.GetItems();
}
}
The Templatestorage, which shows the various attempts at sorting (commented out) is:
public class TemplateStorage
{
private IList<NanoMemoTemplate> templates;
private const string Filename = "template-list.xml";
protected IList<NanoMemoTemplate> Templates
{
get
{
return templates ?? (templates = LoadTemplates().ToList());
}
set
{
templates = value;
}
}
protected IEnumerable<NanoMemoTemplate> LoadTemplates()
{
using(var applicationStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if(!applicationStorage.FileExists(Filename))
return Enumerable.Empty<NanoMemoTemplate>();
using(var speedListFile = applicationStorage.OpenFile(Filename, FileMode.Open, FileAccess.Read))
{
var document = XDocument.Load(speedListFile);
return from t in document.Root.Elements("template")
select new NanoMemoTemplate
{
Id = new Guid(t.Attribute("id").Value),
Subject = t.Attribute("subject").Value,
Body = t.Attribute("body").Value,
DT = t.Attribute("dateCreated").Value,
};
}
}
}
//public IEnumerable<NanoMemoTemplate> SortTemplates()
//{
// using (var applicationStorage = IsolatedStorageFile.GetUserStoreForApplication())
// {
// if (!applicationStorage.FileExists(Filename))
// return Enumerable.Empty<NanoMemoTemplate>();
// using (var speedListFile = applicationStorage.OpenFile(Filename, FileMode.Open, FileAccess.ReadWrite))
// {
// var documentSort = XDocument.Load(speedListFile);
// XDocument datatemp = new XDocument(documentSort);
// var subjectSort = from p in datatemp.Descendants("template")
// orderby (string)p.Attribute("subject")
// select p;
// //var subjectSort = datatemp.Elements("template").OrderBy(p => (string)p.Attribute("subject")).ToArray();
// string cleanDataDump = subjectSort.ToString();
// MessageBox.Show(cleanDataDump);
// documentSort.Descendants("template").Remove();
// documentSort.Element("template").Add(subjectSort);
// return Templates;
// }
// }
//}
//public IEnumerable<NanoMemoTemplate> SortItems()
//{
// //Sort XML order so order is saved
// using (var applicationStorage = IsolatedStorageFile.GetUserStoreForApplication())
// {
// if (!applicationStorage.FileExists(Filename))
// return Enumerable.Empty<NanoMemoTemplate>();
// using (var speedListFile = applicationStorage.OpenFile(Filename, FileMode.Open, FileAccess.ReadWrite))
// {
// var documentSort = XDocument.Load(speedListFile);
// IEnumerable<string> codes = from code in documentSort.Elements("template")
// let subs = (string)code.Element("subject")
// orderby subs
// select subs;
// //return Templates as per usual as sorting is done at DB level
// return from t in documentSort.Root.Elements("template")
// select new NanoMemoTemplate
// {
// Id = new Guid(t.Attribute("id").Value),
// Subject = t.Attribute("subject").Value,
// Body = t.Attribute("body").Value,
// DT = t.Attribute("dateCreated").Value,
// };
// }
// }
//}
public IEnumerable<NanoMemoTemplate> GetItems()
{
return Templates;
}
public void Save(NanoMemoTemplate template)
{
Templates.Add(template);
}
public void Delete(NanoMemoTemplate template)
{
Templates.Remove(template);
}
//public void Sort(NanoMemoTemplate template)
//{
// IList<NanoMemoTemplate> list = new List<NanoMemoTemplate>();
// IEnumerable<NanoMemoTemplate> sortedEnum = list.OrderBy(Templates => Templates.Subject);
// IList<NanoMemoTemplate> sortedList = sortedEnum.ToList();
//}
public void SaveChanges()
{
using(var applicationStorage = IsolatedStorageFile.GetUserStoreForApplication())
using(var speedListFile = applicationStorage.OpenFile(Filename, FileMode.Create, FileAccess.Write))
{
var document = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
new XElement("templates",
from t in Templates
select new XElement("template",
new XAttribute("id", t.Id),
new XAttribute("subject", t.Subject),
new XAttribute("body", t.Body),
new XAttribute("dateCreated", t.DT))));
document.Save(speedListFile);
}
}
}
Instead of having to set Templates.ItemsSource = storage.GetItems(); in your code, you can keep an ObservableCollection (or other enumerable type) as a class-level variable:
//StorageTemplates should be a class-level variable
ObservableCollection<NanoMemoTemplate> StorageTemplates;
//You can assign the value to StorageTemplates when the page loads
StorageTemplates = storage.GetItems();
You would then apply an ItemsSource="{Binding StorageTemplates}" data binding to your ListBox in XAML. (See this for more info on binding)
<ListBox x:Name="Templates" ItemsSource="{Binding StorageTemplates, UpdateSourceTrigger="PropertyChanged"}" SelectionChanged="OnSelectionChanged" Background="Transparent" Style="{StaticResource ListBoxStyle1}" >
<ListBox.ItemTemplate>
....
</ListBox.ItemTemplate>
</ListBox>
Then you can use the built-in Sort methods of the ObservableCollection to set your sort order for the items. You may need to implement a Property Changed handler, you can check this tutorial for more information.

Categories

Resources