Where to use NSString * = [DateCreated stringValue] in Obj-C? - c#

so I am coding a desktop application for Mac OS using C# and Obj-c, but am struggling to get the text from an NSTextBox as a string.
This is the returned code from ViewController.Designer.Cs (the code returned to Visual Studio from Xcode after designing the interface.
using Foundation;
using System.CodeDom.Compiler;
using static System.Net.Mime.MediaTypeNames;
namespace ByteOrbitPrivacyCannonMacBuild
{
[Register("ViewController")]
partial class ViewController
{
[Outlet]
AppKit.NSImageView BackgroundImage { get; set; }
[Outlet]
AppKit.NSButton ClickButtonDecrypt { get; set; }
public static string dtime;
[Outlet]
public static AppKit.NSTextField DateCreated { get; set; }
[Outlet]
AppKit.NSButton Decrypt { get; set; }
[Outlet]
AppKit.NSButton Encrypt { get; set; }
[Outlet]
AppKit.NSTextField Message { get; set; }
[Action ("ClickDecrypt:")]
partial void ClickDecrypt (Foundation.NSObject sender);
[Action ("ClickEncrypt:")]
partial void ClickEncrypt (Foundation.NSObject sender);
[Action ("datecreated:")]
partial void datecreated (Foundation.NSObject sender);
[Action ("Okay:")]
partial void Okay (Foundation.NSObject sender);
void ReleaseDesignerOutlets ()
{
if (DateCreated != null) {
DateCreated.Dispose ();
DateCreated = null;
}
if (BackgroundImage != null) {
BackgroundImage.Dispose ();
BackgroundImage = null;
}
if (ClickButtonDecrypt != null) {
ClickButtonDecrypt.Dispose ();
ClickButtonDecrypt = null;
}
if (Decrypt != null) {
Decrypt.Dispose ();
Decrypt = null;
}
if (Encrypt != null) {
Encrypt.Dispose ();
Encrypt = null;
}
if (Message != null) {
Message.Dispose ();
Message = null;
}
}
}
}
And this the ViewController code.
The
public static AppKit.NSTextField DateCreated { get; set; }
Is the returned code for the NSTextBox called DateCreated, which I am attempting to get the text string from.
Here is the ViewController:
using System;
using System.IO;
using AppKit;
using Foundation;
using UserNotifications;
using static System.Net.Mime.MediaTypeNames;
namespace ByteOrbitPrivacyCannonMacBuild
{
public partial class ViewController : NSViewController
{
public ViewController(IntPtr handle) : base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Do any additional setup after loading the view.
}
public override NSObject RepresentedObject
{
get
{
return base.RepresentedObject;
}
set
{
base.RepresentedObject = value;
// Update the view, if already loaded.
}
}
public static string ctime;
partial void ClickDecrypt(Foundation.NSObject sender)
{
string decrypt;
StreamReader sr = new StreamReader(#"/Users/bopc/encryptedmessagehere.txt");
string line = sr.ReadLine();
decrypt = Encryptor1.Decrypted(Convert.ToString(line));
Message.StringValue = line;
}
StreamReader sr = new StreamReader(#"encryptedmessagehere.txt");
public static string verify;
public static string verifytry;
partial void ClickEncrypt(Foundation.NSObject sender)
{
verify = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss tt");
string enctxt = Encryptor1.Encrypt(Message + " Message Created at: " + verify);
string strPath = Environment.GetFolderPath(
System.Environment.SpecialFolder.DesktopDirectory);
System.IO.File.WriteAllText(#"/Users/bopc/encryptedmessagehere.txt", enctxt);
}
}
}
I am wondering where to put the NSString * = [DateCreated stringValue] in Obj-C? Everywhere I put it returns the error "stringValue does not exist in the current context". New to MacOS development. Thank you.
Edited code:
[Outlet]
public static AppKit.NSTextField DateCreated { get; set; }
unsafe
NSString* myStr = [DateCreated stringValue];
Added after advice:
[Outlet]
public AppKit.NSTextField DateCreated { get; private set; }
Console.WriteLine(DateCreated.StringValue)

When you use Xamarin you code it like so..
var textfield = new NSTextField(new CGRect(0, 0, 300, 100));
textfield.StringValue = "Hello World!";
//or
NSTextField textfield = new NSTextField();
textfield.BackgroundColor = NSColor.Clear;
textfield.Bordered = false;
textfield.Selectable = false;
textfield.Editable = false;
textfield.StringValue = NSString.Create("Hello World!")
and the other way around
NSString text = new NSString();
text = textfield.StringValue;
NSString text = null;
text = "Hello World!"
NSTextField textfield = new NSTextField();
textfield.StringValue = text;
//vs.
textfield.StringValue = NSString.Create(text);
spot the differences when NSString is used as setter and getter. And when C# string is involved.

Related

Trying to load data from API when Pin is clicked (CustomMap) error: Specified cast is not valid. - xamarin.forms.maps

I'm trying to load the data from API in custom map (xamarin.forms.maps) when user click on pin to send (index + 1) on the pin like as parameter.
1. Here I set index + 1 on the Address property on the pin:
List<CustomPin> pins = new List<CustomPin>();
for (int i = 0; i < HardcodedLocations.Positions.Count; i++)
{
CustomPin pin = new CustomPin
{
Type = PinType.Place,
Position = HardcodedLocations.Positions[i],
Label = "Xamarin San Francisco Office",
Address = $"{i + 1}",
Name = "Xamarin",
Url = "http://xamarin.com/about/"
};
pins.Add(pin);
customMap.Pins.Add(pin);
customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(42.8742, 25.3187), Distance.FromKilometers(250.0)));
}
customMap.CustomPins = pins;
2. In CustomMKAnnotationView class I create property Address:
public class CustomMKAnnotationView : MKAnnotationView
{
public string Name { get; set; }
public string Url { get; set; }
public string Address { get; set; }
public CustomMKAnnotationView(IMKAnnotation annotation, string id)
: base(annotation, id)
{
}
3. In GetViewForAnnotation method in CustomMapRenderer class I appropriate annotationView.Address to be equal on customPin.Address
protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
{
MKAnnotationView annotationView = null;
if (annotation is MKUserLocation)
return null;
var customPin = GetCustomPin(annotation as MKPointAnnotation);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
annotationView = mapView.DequeueReusableAnnotation(customPin.Name);
if (annotationView == null)
{
annotationView = new CustomMKAnnotationView(annotation, customPin.Name);
annotationView.Image = UIImage.FromFile("pin.png");
annotationView.CalloutOffset = new CGPoint(0, 0);
annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile("monkey.png"));
annotationView.RightCalloutAccessoryView = UIButton.FromType(UIButtonType.DetailDisclosure);
((CustomMKAnnotationView)annotationView).Name = customPin.Name;
((CustomMKAnnotationView)annotationView).Url = customPin.Url;
((CustomMKAnnotationView)annotationView).Address = customPin.Address;
}
annotationView.CanShowCallout = true;
return annotationView;
}
4. I create a method to get the data from API in CustomMapRenderer class:
string GenerateRequestUri(string endpoint, string date, string id)
{
string requestUri = endpoint;
requestUri += $"?date={date}";
requestUri += $"&id={id}";
requestUri += $"&daysForward=8";
return requestUri;
}
public async Task<IEnumerable<AladinModel>> GetDataFromAPI(string indexOnClick)
{
DateTime dtNow = DateTime.Now;
var dtNowAPI = dtNow.ToString("yyyy-MM-dd");
var listData = new List<AladinModel>();
var result = await _restServiceAPI.GetAladinData(GenerateRequestUri(ConstantsAPI.EndPoint, dtNowAPI, indexOnClick));
foreach (var item in result)
{
var currentData = new AladinModel()
{
Dats = item.Dats,
Ta = item.Ta,
Rh = item.Rh,
Ws = item.Ws,
Rr = item.Rr,
Sr = item.Sr,
Apres = item.Apres
};
listData.Add(currentData);
}
return listData;
}
5. In OnDidSelectAnnotationView method I trying to send the data with MessagingCenter:
void OnDidSelectAnnotationView(object sender, MKAnnotationViewEventArgs e)
{
CustomMKAnnotationView customView = e.View as CustomMKAnnotationView;
customPinView = new UIView();
if (customView.Name.Equals("Xamarin"))
{
customPinView.Frame = new CGRect(0, 0, 200, 84);
var image = new UIImageView(new CGRect(0, 0, 200, 84));
image.Image = UIImage.FromFile("xamarin.png");
customPinView.AddSubview(image);
customPinView.Center = new CGPoint(0, -(e.View.Frame.Height + 75));
e.View.AddSubview(customPinView);
}
string addressIndex = customView.Address;
var result = GetDataFromAPI(addressIndex);
MessagingCenter.Send<object, IEnumerable<AladinModel>>(this, "PinSelected", (IEnumerable<AladinModel>)result);
}
6. In MainPage I trying to receive the data like that:
protected override void OnAppearing()
{
base.OnAppearing();
MarkerPressed();
}
public void MarkerPressed()
{
MessagingCenter.Subscribe<object, IEnumerable<AladinModel>>(this, "PinSelected", (sender, arg) =>
{
var test = arg;
});
}
When I click on the marker I receive error: Specified cast is not valid on this line:
MessagingCenter.Send<object, IEnumerable<AladinModel>>(this, "PinSelected", (IEnumerable<AladinModel>)result);
Đ¢his is my object class:
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace pizhevsoft.Models
{
public class ItemsAPI
{
public partial class RootAladinModel
{
[JsonProperty("aladinModel")]
public AladinModel[] AladinModel { get; set; }
}
public partial class AladinModel
{
[JsonProperty("DATS")]
public DateTime Dats { get; set; }
[JsonProperty("TA")]
public double Ta { get; set; }
[JsonProperty("RH")]
public double Rh { get; set; }
[JsonProperty("WS")]
public double Ws { get; set; }
[JsonProperty("RR")]
public double Rr { get; set; }
[JsonProperty("SR")]
public double Sr { get; set; }
[JsonProperty("APRES")]
public double Apres { get; set; }
}
}
}
The main goal when clicking on the marker is to take its index + 1, to pass it as a parameter to API to get the data ?
If there is an easier option or way to deal with the problem please share how to do it?
According to my logic, a method GetDataFromAPI must be created in the CustomMapRenderer class, to be called in OnDidSelectAnnotationView, and data to be sending to the Main project with messaging center ?
GetDataFromAPI is an async method and needs to be called using await

Items not showing in recycler view Xamarin android

I am implementing recycler view in my Xamarin android application, But Items are not showing on debugging the application altough the InitData() Method is properly executed.
Here is the mainactivity.cs code in which recycler view is implemented:
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FinalProject_PU.Helper
{
class Data
{
public string IssueImage { get; set; }
public string UserImage { get; set; }
public string UserName { get; set; }
public DateTime IssueDate { get; set; }
public string IssueStatement { get; set; }
public int GetElevatedDates()
{
var ElevatedDays = (IssueDate.Date - DateTime.Now.Date).Days;
return ElevatedDays;
}
public string ElevatedDays
{
get { return ElevatedDays; }
set
{
if (GetElevatedDates() == 0)
{
ElevatedDays = "Today";
}
else
{
ElevatedDays = GetElevatedDates() + "Days";
}
}
}
}
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
SetContentView(Resource.Layout.Home);
byte[] arr = Convert.FromBase64String(UserInfoHolder.Profile_pic);
imgwriteIssue = (ImageView)FindViewById(Resource.Id.imgwriteIssue);
imgwriteIssue.Click += delegate
{
var i = new Intent(this, typeof(CreateIssue));
this.StartActivity(i);
};
CircleImageView img = FindViewById<CircleImageView>(Resource.Id.circleImageView1);
Android.Graphics.Bitmap bitmap = BitmapFactory.DecodeByteArray(arr, 0, arr.Length);
img.SetImageBitmap(bitmap);
iconfunds = (ImageView)FindViewById(Resource.Id.iconFunds);
iconfunds.Click += Iconfunds_Click;
notifications = (ImageView)FindViewById(Resource.Id.iconNotifications);
notifications.Click += Notifications_Click;
map = (ImageView)FindViewById(Resource.Id.iconMap);
map.Click += Map_Click;
setting = (ImageView)FindViewById(Resource.Id.iconSettings);
setting.Click += Setting_Click;
recycler = FindViewById<RecyclerView>(Resource.Id.recyclerView1);
recycler.HasFixedSize = true;
// layoutManager = new LinearLayoutManager(this);
layoutManager = new GridLayoutManager(this, 1, GridLayoutManager.Horizontal, false);
recycler.SetLayoutManager(layoutManager);
InitData();
adapter = new RecyclerViewAdapter(lstData);
recycler.SetAdapter(adapter);
}
private async void InitData()
{
lstData = await IssueController.FetchPostList();
}
fetchallpost() method fetch all the issues from data and return a list of it.
but it is not showing in recycler view and application is halting in a few seconds after opening Homeactivity.cs
Here is the recycler view adapter class on which my programs breaks automatially
RecyclerViewAdapter.cs
using Android.Support.V7.Widget;
using Android.Views;
using Android.Widget;
using Refractored.Controls;
using System.Collections.Generic;
using System;
using Android.Content;
using AndroidX.Core.Graphics;
namespace FinalProject_PU.Helper
{
class RecyclerViewHolder : RecyclerView.ViewHolder
{
public ImageView imageview { get; set; }
public CircleImageView UserImage { get; set; }
public TextView UserName { get; set; }
public TextView IssueDate { get; set; }
public TextView IssueStatement { get; set; }
Android.Graphics.Typeface tf;
//
// public TextView Description { get; set; }
public RecyclerViewHolder(Android.Views.View itemView) : base(itemView)
{
imageview = itemView.FindViewById<ImageView>(Resource.Id.imageView1);
UserImage = itemView.FindViewById<CircleImageView>(Resource.Id.imgProfile);
UserName = itemView.FindViewById<TextView>(Resource.Id.tvname);
IssueDate = itemView.FindViewById<TextView>(Resource.Id.tvtime);
IssueStatement = itemView.FindViewById<TextView>(Resource.Id.tvinfo);
//beauttification
/*
tf = Typeface.CreateFromAsset(Assets, "Quicksand-Bold.otf");
IssueStatement.SetTypeface(tf, TypefaceStyle.Bold);
tf = Typeface.CreateFromAsset(Assets, "Quicksand-Bold.otf");
UserName.SetTypeface(tf, TypefaceStyle.Bold);
tf = Typeface.CreateFromAsset(Assets, "Quicksand-Bold.otf");
IssueDate.SetTypeface(tf, TypefaceStyle.Bold);
*/
}
}
class RecyclerViewAdapter : RecyclerView.Adapter
{
private List<Data> lstData = new List<Data>();
public RecyclerViewAdapter(List<Data> lstData)
{
this.lstData = lstData;
}
public override int ItemCount
{
get
{
return lstData.Count;
}
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
RecyclerViewHolder viewHolder = holder as RecyclerViewHolder;
byte[] arr0 = Convert.FromBase64String(lstData[position].IssueImage); //IssueImage
Bitmap b0 = BitmapFactory.DecodeByteArray(arr0, 0, arr0.Length);
viewHolder.imageview.SetImageBitmap(b0);
byte[] arr1 = Convert.FromBase64String(lstData[position].UserImage); //UserImage
Bitmap b1 = BitmapFactory.DecodeByteArray(arr1, 0, arr1.Length);
viewHolder.UserImage.SetImageBitmap(b1); //
viewHolder.UserName.Text = lstData[position].UserName;
viewHolder.IssueDate.Text = lstData[position].ElevatedDays;
viewHolder.IssueStatement.Text = lstData[position].IssueStatement;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
LayoutInflater inflater = LayoutInflater.From(parent.Context);
Android.Views.View itemView = inflater.Inflate(Resource.Layout.items, parent, false);
return new RecyclerViewHolder(itemView);
}
}
}```
I have tried debugging the application to see what is causing the problem and it was found out that application is breaking when it reaches on this line in recycler view constructor.
I have made sure that the fetchallpost() method is actually returning list with data.
imageview = itemView.FindViewById<ImageView>(Resource.Id.imageView1);
please help me with this

Merging C# code in Xamarin Android

I got the code of detecting poor grammar from here - Detecting Poor grammar
I am new to C# and Xamarin. I want to merge this code into my speech to text conversion app.
I tried to do it, but I am not getting the desired results.
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Widget;
using Android.OS;
using Android.Speech;
using Android.Util;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net;
namespace SpeechToText
{
[Activity(Label = "SpeechToText", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity, IRecognitionListener
{
public const string Tag = "VoiceRec";
SpeechRecognizer Recognizer { get; set; }
Intent SpeechIntent { get; set; }
TextView Label { get; set; }
TextView Label1 { get; set; }
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
Recognizer = SpeechRecognizer.CreateSpeechRecognizer(this);
Recognizer.SetRecognitionListener(this);
SpeechIntent = new Intent(RecognizerIntent.ActionRecognizeSpeech);
SpeechIntent.PutExtra(RecognizerIntent.ExtraLanguageModel, RecognizerIntent.LanguageModelFreeForm);
SpeechIntent.PutExtra(RecognizerIntent.ExtraCallingPackage, PackageName);
var button = FindViewById<Button>(Resource.Id.btn);
button.Click += ButtonClick;
var Grammarbutton = FindViewById<Button>(Resource.Id.btn1);
Grammarbutton.Click += new EventHandler(ButtonClick2);
Label = FindViewById<TextView>(Resource.Id.tv);
Label1 = FindViewById<TextView>(Resource.Id.tv1);
}
private void ButtonClick(object sender, EventArgs e)
{
Recognizer.StartListening(SpeechIntent);
}
public void OnResults(Bundle results)
{
var matches = results.GetStringArrayList(SpeechRecognizer.ResultsRecognition);
if (matches != null && matches.Count > 0)
{
Label.Text = matches[0];
}
}
private void ButtonClick2(object sender, EventArgs e)
{
var api = new GingerItApi();
for (; ; )
{
Console.Write("Text to check: ");
var text = Label.Text;
if (string.IsNullOrEmpty(text)) break;
try
{
var result = api.Check(text);
if (result?.Corrections?.Count != 0)
{
for (int i = 0; i < result.Corrections.Count; i++)
{
var item = result.Corrections[i];
var mistakes = string.Join(", ", item.Mistakes.Select(x => $"\"{text.Substring(x.From, x.To - x.From + 1)}\""));
var suggestions = string.Join(", ", item.Suggestions.Select(x => $"\"{x.Text}\""));
Label1.Text = $" {i + 1}: {mistakes} >> {suggestions}";
}
}
else
{
Console.WriteLine("Looks okay.\n");
}
}
catch (Exception ex)
{
Console.WriteLine($"**Error: {ex.Message}\n");
}
}
}
public void OnReadyForSpeech(Bundle #params)
{
Log.Debug(Tag, "OnReadyForSpeech");
}
public void OnBeginningOfSpeech()
{
Log.Debug(Tag, "OnBeginningOfSpeech");
}
public void OnEndOfSpeech()
{
Log.Debug(Tag, "OnEndOfSpeech");
}
public void OnError([GeneratedEnum] SpeechRecognizerError error)
{
Log.Debug("OnError", error.ToString());
}
public void OnBufferReceived(byte[] buffer) { }
public void OnEvent(int eventType, Bundle #params) { }
public void OnPartialResults(Bundle partialResults) { }
public void OnRmsChanged(float rmsdB) { }
}
}
class GingerItApi
{
public CheckResult Check(string text)
{
var request = WebRequest.Create($"https://services.gingersoftware.com/Ginger/correct/jsonSecured/GingerTheTextFull?callback=jQuery172015406464511272344_1490987331365&apiKey=GingerWebSite&lang=US&clientVersion=2.0&text={text}&_=1490987518060") as HttpWebRequest;
WebResponse response = null;
try
{
response = request.GetResponse();
if (response != null)
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
string data = reader.ReadToEnd();
var first = data.IndexOf('{');
var last = data.LastIndexOf('}');
var json = data.Substring(first, last - first + 1);
return JsonConvert.DeserializeObject<CheckResult>(json);
}
}
}
catch (Exception)
{
throw;
}
return null;
}
}
public class LrnFrgOrigIndx
{
[JsonProperty("From")]
public int From { get; set; }
[JsonProperty("To")]
public int To { get; set; }
}
public class Mistake
{
[JsonProperty("Definition")]
public string Definition { get; set; }
[JsonProperty("CanAddToDict")]
public bool CanAddToDict { get; set; }
[JsonProperty("From")]
public int From { get; set; }
[JsonProperty("To")]
public int To { get; set; }
}
public class Suggestion
{
[JsonProperty("Definition")]
public string Definition { get; set; }
[JsonProperty("LrnCatId")]
public int LrnCatId { get; set; }
[JsonProperty("Text")]
public string Text { get; set; }
}
public class Correction
{
[JsonProperty("Confidence")]
public int Confidence { get; set; }
[JsonProperty("From")]
public int From { get; set; }
[JsonProperty("LrnFrg")]
public string LrnFrg { get; set; }
[JsonProperty("LrnFrgOrigIndxs")]
public IList<LrnFrgOrigIndx> LrnFrgOrigIndxs { get; set; }
[JsonProperty("Mistakes")]
public IList<Mistake> Mistakes { get; set; }
[JsonProperty("ShouldReplace")]
public bool ShouldReplace { get; set; }
[JsonProperty("Suggestions")]
public IList<Suggestion> Suggestions { get; set; }
[JsonProperty("To")]
public int To { get; set; }
[JsonProperty("TopLrnCatId")]
public int TopLrnCatId { get; set; }
[JsonProperty("Type")]
public int Type { get; set; }
[JsonProperty("UXFrgFrom")]
public int UXFrgFrom { get; set; }
[JsonProperty("UXFrgTo")]
public int UXFrgTo { get; set; }
}
public class Sentence
{
[JsonProperty("FromIndex")]
public int FromIndex { get; set; }
[JsonProperty("IsEnglish")]
public bool IsEnglish { get; set; }
[JsonProperty("ToIndex")]
public int ToIndex { get; set; }
}
public class CheckResult
{
[JsonProperty("Corrections")]
public IList<Correction> Corrections { get; set; }
[JsonProperty("Sentences")]
public IList<Sentence> Sentences { get; set; }
}
I want to get the recognized speech, send it to grammar corrector, and display the output.
Please help me to solve this, or at least help me to further research the problem.
Thank you.
You have put an infinite loop in your code. Please remove it.
For example:
private void ButtonClick2(object sender, EventArgs e)
{
var api = new GingerItApi();
Console.Write("Text to check: ");
var text = Label.Text;
if (!string.IsNullOrEmpty(text))
{
try
{
var result = api.Check(text);
if (result?.Corrections?.Count != 0)
{
for (int i = 0; i < result.Corrections.Count; i++)
{
var item = result.Corrections[i];
var mistakes = string.Join(", ", item.Mistakes.Select(x => $"\"{text.Substring(x.From, x.To - x.From + 1)}\""));
var suggestions = string.Join(", ", item.Suggestions.Select(x => $"\"{x.Text}\""));
Label1.Text = $" {i + 1}: {mistakes} >> {suggestions}";
}
}
else
{
Label1.Text = "Looks okay.\n";
Console.WriteLine("Looks okay.\n");
}
}
catch (Exception ex)
{
Console.WriteLine($"**Error: {ex.Message}\n");
}
}
}
And the result is:

Reading existing json and add new record

I am trying to build an app that will allow users to add new entries to a local json file. I can easily write the record to a file but I cannot get it to update it. Here is the code I have at this point:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
...
public partial class frmGvhs : Form
{
List<FacultyMember> memberList = new List<FacultyMember>();
String filename = #"C:\Users\John\test.json";
public frmGvhs()
{
InitializeComponent();
}
private void btnSave_Click(object sender, EventArgs e)
{
FacultyMember member = new FacultyMember();
member.firstName = txtFirstName.Text;
member.lastName = txtLastName.Text;
member.email = txtEmail.Text;
member.ext = txtExt.Text;
member.department = cmbDepartments.Text;
memberList.Add(member);
String json = JsonConvert.SerializeObject(memberList.ToArray());
System.IO.File.WriteAllText(filename, json);
}
private void frmGvhs_Load(object sender, EventArgs e)
{
if (System.IO.File.Exists(filename))
{
System.IO.StreamReader re = new System.IO.StreamReader(filename);
JsonTextReader reader = new JsonTextReader(re);
JsonSerializer se = new JsonSerializer();
object parsedData = se.Deserialize(reader);
String json = JsonConvert.SerializeObject(parsedData);
Console.Write(json);
}
}
}
public class FacultyMember
{
public String firstName { get; set; }
public String lastName { get; set; }
public String email { get; set; }
public String ext { get; set; }
public String department { get; set; }
public FacultyMember()
{
}
}
Now when the app loads up I see the string of the existing json data. So now since its a string I cannot work with it. Do I need to loop through the object [parsedData]? I would like to basically add the existing data to the List<FacultyMember> memberList variable.
Read file content and deserialize to memberList. Then add them and save again.
memberList = JsonConvert.DeserializeObject<List<FacultyMember>>(System.IO.File.ReadAllText(filename));
Example
class Program
{
static List<FacultyMember> memberList = new List<FacultyMember>();
static String filename = #"C:\test.json";
static void Main(string[] args)
{
Save();
Load();
}
static void AddNew()
{
FacultyMember member = new FacultyMember();
member.firstName = "Test";
member.lastName = "Test";
member.email = "test";
member.ext = "test";
member.department = "Test";
memberList.Add(member);
Save();
}
static void Save()
{
String json = JsonConvert.SerializeObject(memberList);
System.IO.File.WriteAllText(filename, json);
}
static void Load()
{
memberList = JsonConvert.DeserializeObject<List<FacultyMember>>(System.IO.File.ReadAllText(filename));
AddNew();
Save();
}
}
A couple of things:
You need to deserialize as the type of object you want then cast the result (in this case an array of FacultyMembers.
When you read from the file you should surround it with a using statement so it closes.
Here is a sample:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
public class Foo
{
static String filename = #"C:\test.json";
public static void Save()
{
FacultyMember member = new FacultyMember();
member.firstName = Guid.NewGuid().ToString();
member.lastName = "Bar";
member.email = "Email";
member.ext = "Ext";
member.department = "Dept";
List<FacultyMember> existing = new List<FacultyMember>();
existing.AddRange(Load());
existing.Add(member);
String json = JsonConvert.SerializeObject(existing.ToArray());
System.IO.File.WriteAllText(filename, json);
}
public static FacultyMember[] Load()
{
if (System.IO.File.Exists(filename))
{
using (System.IO.StreamReader re = new System.IO.StreamReader(filename))
{
JsonTextReader reader = new JsonTextReader(re);
JsonSerializer se = new JsonSerializer();
object obj = se.Deserialize(reader, typeof (FacultyMember[]));
return (FacultyMember[]) obj;
}
}
return new FacultyMember[0];
}
}
public class FacultyMember
{
public String firstName { get; set; }
public String lastName { get; set; }
public String email { get; set; }
public String ext { get; set; }
public String department { get; set; }
public FacultyMember()
{
}
}

Drawing polyline with JSON data on Windows Phone Map application

I am trying to draw a polyline using the "PATH" from the JSON data after clicking on the "Draw Polyline" button. However I met with this error,
"An exception of type 'System.ArgumentException' occurred in ESRI.ArcGIS.Client.DLL but was not handled in user code
Additional information: Invalid geometry."
Am I missing any codes?
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Geometry;
using ESRI.ArcGIS.Client.Symbols;
using ESRI.ArcGIS.Client.Tasks;
using ESRI.ArcGIS.Client.Toolkit.DataSources;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Maps.Controls;
using Microsoft.Phone.Shell;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Device.Location;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;
using Test.Resources;
namespace Test
{
public partial class MainPage : PhoneApplicationPage
{
private String finalPath;
GraphicsLayer _myFromJsonGraphicsLayer;
Draw _myDrawObject;
// Constructor
public MainPage()
{
InitializeComponent();
_myFromJsonGraphicsLayer = MyMap.Layers["MyFromJsonGraphicsLayer"] as GraphicsLayer;
_myDrawObject = new Draw(MyMap)
{
LineSymbol = LayoutRoot.Resources["DrawLineSymbol"] as LineSymbol,
FillSymbol = LayoutRoot.Resources["DrawFillSymbol"] as FillSymbol
};
_myDrawObject.DrawComplete += MyDrawObject_DrawComplete;
}
private void MyDrawObject_DrawComplete(object sender, ESRI.ArcGIS.Client.DrawEventArgs args)
{
Graphic graphic = new Graphic()
{
Geometry = args.Geometry,
Symbol = LayoutRoot.Resources["RedFillSymbol"] as FillSymbol
};
GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
graphicsLayer.Graphics.Add(graphic);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//base.OnNavigatedTo(e);
setUpLayers();
// Create webclient.
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
//client.DownloadStringAsync(new Uri("http://www.onemap.sg/publictransportation/service1.svc/routesolns?token=qo/s2TnSUmfLz+32CvLC4RMVkzEFYjxqyti1KhByvEacEdMWBpCuSSQ+IFRT84QjGPBCuz/cBom8PfSm3GjEsGc8PkdEEOEr&sl="+startX+","+startY+"&el="+endX+","+endY+"&startstop=&endstop=&walkdist=300&mode=bus&routeopt=cheapest&retgeo=true&maxsolns=1&callback="));
client.DownloadStringAsync(new Uri("http://www.onemap.sg/publictransportation/service1.svc/routesolns?token=qo/s2TnSUmfLz+32CvLC4RMVkzEFYjxqyti1KhByvEacEdMWBpCuSSQ+IFRT84QjGPBCuz/cBom8PfSm3GjEsGc8PkdEEOEr&sl=39167.4524,35518.8625&el=28987.5163,33530.5653&startstop=&endstop=&walkdist=300&mode=bus&routeopt=cheapest&retgeo=true&maxsolns=1&callback="));
}
private void setUpLayers()
{
ArcGISTiledMapServiceLayer baseMapLayer = new ArcGISTiledMapServiceLayer();
baseMapLayer.ID = "BaseMap";
baseMapLayer.Url = "http://e1.onemap.sg/arcgis/rest/services/SM128/MapServer";
//baseMapLayer.Url = "http://onemap.sg/arcgis/rest/services/Basemap/MapServer";
MyMap.Layers.Add(baseMapLayer);
}
public class STEP
{
//public string STEP { get; set; }
public string type { get; set; }
public string ServiceType { get; set; }
public string ServiceID { get; set; }
public string NumberOfStop { get; set; }
public string BoardId { get; set; }
public string BoardDesc { get; set; }
public string BoardDist { get; set; }
public string AlightId { get; set; }
public string AlightDesc { get; set; }
public string AlightDist { get; set; }
}
public class BusRoute
{
public string Solution { get; set; }
public string Duration { get; set; }
public string TotalCard { get; set; }
public string TotalCash { get; set; }
public string TotalDistance { get; set; }
public List<STEP> STEPS { get; set; }
public string TotalStops { get; set; }
public List<List<string>> PATH { get; set; }
}
public class RootObject
{
public List<BusRoute> BusRoute { get; set; }
}
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
// var rootObject = JsonConvert.DeserializeObject<RootObject>(e.Result);
JObject rawData = JObject.Parse(e.Result);
String path = rawData["BusRoute"][0]["PATH"].ToString();
String[] collectionOfPoints = path.Split(';');
//JObject path = JObject.Parse(rawData["BusRoute"].ToString());
finalPath = "";
for (int i = 0; i < collectionOfPoints.Length; i++)
{
if (i == 0)
{
finalPath = #"{""paths"":[" + collectionOfPoints[i] + "]";
finalPath = finalPath + ",";
}
else if (i == collectionOfPoints.Length - 1)
{
finalPath = finalPath + "[" + collectionOfPoints[i] + "],\"spatialReference\":{\"wkid\":4326}}";
}
else
{
finalPath = finalPath + "[" + collectionOfPoints[i] + "]";
finalPath = finalPath + ",";
}
}
tb_test.Text = finalPath;
}
private void DrawGeometryButton_Click(object sender, RoutedEventArgs e)
{
ESRI.ArcGIS.Client.Geometry.Geometry geometry = ESRI.ArcGIS.Client.Geometry.Geometry.FromJson(tb_test.Text);
Graphic graphic = new Graphic();
_myDrawObject.DrawMode = DrawMode.Polyline;
tb_test.Text = finalPath;
}
}
}

Categories

Resources