Write/read to object - windows-phone-7

I would like to make a simple way to write/read to object element in WP7. Something is not working properly. My way of thinking and what I have already done is like that:
First I create a class that represents my object. I added static string just to see if everything works well:
namespace SimpleObject.Objects
{
public class Entry
{
public string entrytitle { get; set; }
public string entrycomment { get; set; }
public string entrycat = "works";
public Entry() { }
public Entry(string Entrytitle, string Entrycomment, string Entrycat)
{
this.entrytitle = Entrytitle;
this.entrycomment = Entrycomment;
this.entrycat = Entrycat;
}
public string entry { get; set; }
}
}
Then, as I read in some articles I need to make some changes in App.xaml.cs Here we go then:
using SimpleObject.Objects;
Before App() I put this:
public static Entry E;
Then in App() this:
UnhandledException += new EventHandler<ApplicationUnhandledExceptionEventArgs>(Application_UnhandledException);
E = new Entry();
InitializeComponent();
Then my UI is two pages. One is a form to input data, second to read. Under application bar button I have:
private void ApplicationBarIconButton_Click(object sender, System.EventArgs e)
{
Entry E = new Entry
{
entrytitle = TitleTextBox.Text,
entry = CommentTextBox.Text,
};
this.NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));
MessageBox.Show("Category added!");
}
Finally page that present results:
private void button1_Click(object sender, RoutedEventArgs e)
{
TextBlock1.Text = App.E.entrycat;
TextBlock2.Text = App.E.entrytitle;
}
And second TextBlock gives me nothing...

You're never setting the global static values. In your button click, it should be this:
private void ApplicationBarIconButton_Click(object sender, System.EventArgs e)
{
App.E.entrytitle = TitleTextBox.Text,
App.E.entrycat = CommentTextBox.Text,
this.NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));
}

another option is to forgo the global variable which you're basically only using to pass the value from one page to the next.
You can do this with query string values just like in a web application and pick them up on your page load handler.
private void ApplicationBarIconButton_Click(object sender, System.EventArgs e)
{
this.NavigationService.Navigate(new Uri("/Page2.xaml?title=TitleTextBox.Text&comment=CommentTextBox.Text", UriKind.Relative));
}

Related

How to create command menu item with checkbox?

I'm writing a VSPackage and I need to have menu item with checkbox, just like on this sample image below:
I went through this msdn reference regarding .vsct files, bud didn't fine any information explaining how to do it. What I have now is standard menu item with icon and text (code sample from MyPackage.vsct file):
<Buttons>
<Button guid="guidMyPackageCmdSet" id="cmdidMyPackage" type="Button">
<Icon guid="guidImages" id="myPackageBitmap" />
<CommandFlag>TextChanges</CommandFlag>
<CommandFlag>DontCache</CommandFlag>
<CommandFlag>FixMenuController</CommandFlag>
<Strings>
<ButtonText>MyPackage</ButtonText>
</Strings>
</Button>
</Buttons>
I need this additional checkbox. How to do it?
The properties like Checked, Visible, Enabled or Supported can´t be defined via the VSCT file. You need a command handler that controls the command´s state. I´ve created a base class that wraps the creation of the OleMenuCommand instance and handles the command´s BeforeQueryStatus event. This is a slimmed version of my implementation, but it will give you an idea how to solve it...
internal abstract class CommandHandler : IDisposable
{
private readonly OleMenuCommand command;
protected CommandHandler(Guid group, int id)
{
var commandid = CommandID(group, id);
this.command = new OleMenuCommand(this.Invoke, commandId);
this.command.BeforeQueryStatus += this.OnBeforeQueryStatus;
}
protected virtual void OnExecute() { }
protected virtual void OnQueryStatus(QueryStatusEventArgs e) { }
private void Invoke(object sender, EventArgs e)
{
this.OnExecute();
}
private void OnBeforeQueryStatus(object sender, EventArgs e)
{
OleMenuCommand command;
if ((command = sender as OleMenuCommand) != null)
{
var e = new QueryCommandEventArgs
{
Checked = command.Checked,
}
this.OnQueryStatus(e);
command.Checked = e.Checked;
}
}
public void Dispose()
{
this.command.BeforeQueryStatus -= this.OnBeforeQueryStatus;
}
}
public class QueryCommandEventArgs : EventArgs
{
public bool Checked { get; set; }
}
The CommandHandler class allows to control the state of any menu command. Just derive new handler implementations from it and override the OnExecute and OnQueryStatus methods, like...
internal sealed class MyCommand : CommandHandler
{
private bool checked;
public MyCommand() : base(GuidCmdSet, MyCommandId) { }
protected override void OnExecute()
{
this.checked = !this.checked; // toggle checked state
}
protected override void OnQueryStatus(QueryStatusEventArgs e)
{
e.Checked = this.checked;
}
}

Getting a concrete event from WP7 calendar

I'm working on a WP7 application and I need it to play the song in the first link if the current event on the calendar is "Meeting". However, with the current code, it plays the second song instead if the first one even though the event is set correctly.
Here is my code:
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
// Set the data context of the listbox control to the sample data
DataContext = App.ViewModel;
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
// Load data for the ViewModel Items
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Appointments appts = new Appointments();
//Identify the method that runs after the asynchronous search completes.
appts.SearchCompleted += new EventHandler<AppointmentsSearchEventArgs>(Appointments_SearchCompleted);
DateTime start = DateTime.Now;
DateTime end = DateTime.Now;
int max = 1;
//Start the asynchronous search.
appts.SearchAsync(start, end, max, "Appointments Test #1");
textBlock3.Text = DateTime.Now.ToString("hh:mm:ss tt");
}
void Appointments_SearchCompleted(object sender, AppointmentsSearchEventArgs e)
{
try
{
AppointmentResultsDataLINQ.DataContext =
from Appointment appt in e.Results
where appt.IsAllDayEvent == false
select appt;
}
catch (System.Exception)
{
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
if ((AppointmentResultsDataLINQ.DataContext).Equals("Meeting"))
{
mediaElement1.Source = new Uri("http://www.opendrive.com/files/NV8zNTMwNDYwX2hxRXZR/Crystallize.mp3", UriKind.Absolute);
}
else
{
mediaElement1.Source = new Uri("https://www.opendrive.com/files/NV8zMjAxODY0X0VBNDJY/Hetken%20tie%20on%20kevyt%20(piano%20cover)%20-%20YouTube.mp3", UriKind.Absolute);
}
mediaElement1.Play();
}
}
The problem appears to be this line:
if ((AppointmentResultsDataLINQ.DataContext).Equals("Meeting"))
You're comparing the result of calling the ToString() method on the Appointment instance with the string "Meeting".
You probably want:
if ((AppointmentResultsDataLINQ.DataContext as Appointment).Subject.Equals("Meeting"))
Update
You're actually checking an Enumerable of Appointments.
Here's how to check if any of them are "Meeting":
if ((AppointmentResultsDataLINQ.DataContext as IEnumerable<Appointment>).Any(app => app.Subject.Equals("Meeting")))

windows phone loading data from MainViewModel

Noob question probably.
I am developing a mvm wp7 app where the map shows pushpins of salons. The database is retrieved from a link.
The problem i am struggling with is that the observable collection data is not being loaded from the App._ViewModel (where the json serializer parses the database and works fine). On debugging the app shows a plain map and thats all. On returning a string attribute from the database causes a break on that code. i tried messagebox as well to show the string, still crashes.
Heres the code:
mainviewmodel.cs
public class MainViewModel
{
public bool IsDataLoaded { get; private set; }
public ObservableCollection<SalonViewModel> SalonCollection { get; private set; }
public MainViewModel()
{
IsDataLoaded = false;
}
public ObservableCollection<SalonViewModel> LoadData()
{
SalonCollection = new ObservableCollection<SalonViewModel>();
var wednesday = new Uri("http://blehbleh.txt");
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(wednesday);
return SalonCollection;
}
public void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ObservableCollection<SalonViewModel>));
ObservableCollection<SalonViewModel> list = serializer.ReadObject(e.Result) as ObservableCollection<SalonViewModel>;
foreach (SalonViewModel b in list)
{
SalonCollection.Add(new SalonViewModel { sid=b.sid,sname=b.sname,sgeo_lat=b.sgeo_lat,sgeo_lon=b.sgeo_lon,
}
this.IsDataLoaded = true;
}
catch (Exception ex)
{
//throw ex;
MessageBox.Show(ex.Message);
}
}
The App.cs
public partial class App : Application
{
private static MainViewModel viewModel;
public static MainViewModel _viewModel
{
get
{
if (viewModel == null)
{
viewModel = new MainViewModel();
}
return viewModel;
}
}
void LoadData()
{
if (!_viewModel.IsDataLoaded)
{
_viewModel.LoadData();
}
}
etc
Heres the mappage.cs
private void salon_map_Loaded (object sender, RoutedEventArgs e)
{
foreach (SalonViewModel Salon in App._viewModel.LoadData)
{
MessageBox.Show(Salon.sname);
Pushpin p = new Pushpin();
p.Content = Salon.sname + System.Environment.NewLine + "Rate: ";
Layer.AddChild(p, new GeoCoordinate(Salon.sgeo_lon, Salon.sgeo_lat));
}
Map1.Children.Add(Layer);
}
In your MainViewModel LoadData function, OpenReadAsync() is an asynchronous function, and thus returning SalonCollection on the next line will return an empty ObservableCollection, since the callback function wc_OpenReadCompleted has not run yet.
Also, the reason the MessageBox.Show crashes is because you are attempting to call a UI function on a non-UI thread (solution to that here: Dispatcher.Invoke() on Windows Phone 7?)
Instead of returning the ObservableCollection and manually adding children to the map from that, try binding a MapItemsControl layer of the Map to the ObservableCollection of your view model. There's a decent example of doing that here: Binding Pushpins to Bing Maps in Windows Phone

Update data in isolated storage

I have a code that adds email id and name in Isolated space. But it is not able to add multiple data. Also, how can I update in case any data was entered incorrectly?
namespace IsoStore
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
IsolatedStorageSettings.ApplicationSettings.Add("email", "someone#somewhere.com");
IsolatedStorageSettings.ApplicationSettings.Add("name", "myname");
}
private void button2_Click(object sender, RoutedEventArgs e)
{
textBlock1.Text = (string)IsolatedStorageSettings.ApplicationSettings["email"];
textBlock2.Text = (string)IsolatedStorageSettings.ApplicationSettings["name"];
}
}
}
Cleaned up your code a little for you, using a helper method to do the store:
namespace IsoStore
{
public partial class MainPage : PhoneApplicationPage
{
private IsolatedStorageSettings _appSettings;
// Constructor
public MainPage()
{
InitializeComponent();
_appSettings = IsolatedStorageSettings.ApplicationSettings;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
SaveSetting("email", "someone#somewhere.com");
SaveSetting("name", "myname");
}
private void button2_Click(object sender, RoutedEventArgs e)
{
textBlock1.Text = (string)_appSettings["email"];
textBlock2.Text = (string)_appSettings["name"];
}
private void SaveSetting( string setting, string value )
{
if (_appSettings.Contains(setting))
{
_appSettings[setting] = value;
}
else
{
_appSettings.Add(setting, value);
}
}
}
}
Try a few other examples to get your head around using IsolatedStorageSettings.
How to: Store and Retrieve Application Settings Using Isolated Storage
All about WP7 Isolated Storage - Store data in IsolatedStorageSettings
I have in mind 2 options, you either save your data to isolatedStorageFile MSDN Library OR ,this is what i might do in such case, You save under the key email all your emails as one string separate the emails with a char that is not allowed to be in an email, Coma "," lets say, when needed split your string and retrieve it to whatever makes you comfortable.
private void SaveSetting( string setting, string value )
{
if (_appSettings.Contains(setting))
{
_appSettings[settings] = _appSettings[settings] + "," + value;
}
else
{
_appSettings.Add(setting, value);
}
}
please note that this code segment is copied from HiTech Magic' answer.

Porting console based ui to a GUI one?

As most of you experienced, developing a console app is as easy as:
void mainloop(){
while (1){
giveInstructions();
getInput();
if (!process()) break;
printOutput();
}
}
int main(){
mainloop();
return 0;
}
However, in GUI it becomes an issue.
We can still giveInstructions(), process(), and printOutput(), but getInput() wouldn't work because it relies on an event, usually button click or key down.
How can I port a console app to a gui app with minimum code changes? (preferably do not change the main method, and as little change to the mainloop function as possible)
Note: I'm not too comfortable with threading yet.
Since there is no specific language given, I will show an example in C# where you would be able to use the same code as the console app with a simple GUI.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//using form-editor, double-click buttons or use the following
btnInput.Click += new EventHandler(btnInput_Click);
btnContinue.Click += new EventHandler(btnContinue_Click);
giveInstructions();
}
private void giveInstructions()
{
txtInfo.Text = "";
txtInput.Text = "";
//display instructions to multi-line textbox
}
private void btnInput_Click(object sender, EventArgs e)
{
//or you can just add another button for exit.
if (txtInput.Text == "expected value for exit")
{
Application.Exit();
}
else
{
getInput();
}
}
private void getInput()
{
string strInput = txtInput.Text;
//do stuff
printOutput();
}
private void printOutput()
{
//display output to multi-line textbox
}
private void btnContinue_Click(object sender, EventArgs e)
{
giveInstructions();
}
}

Resources