I'm trying to using PhotoChooserTask for our purposes.
After calling photoChooserTask.Show() chooser is showed but when I choose a picture it's closing and event Completed not fired !
Why?
And more, after that PhotoChooserTask not showed next time when calling Show.
P.S. if i try this code in new solution - it will work fine, but why it doesn't work in our project?
PhotoChooserTask photoChooserTask;
private void button2_Click(object sender, System.Windows.RoutedEventArgs e)
{
photoChooserTask = new PhotoChooserTask();
photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
photoChooserTask.Show();
// TODO: Add event handler implementation here.
}
void photoChooserTask_Completed(object sender, PhotoResult e)
{
//Bla bla bla
}
I solved this problem.
So, project CAN NOT have more than one photo chooser.
You can't declare PhotoChooserTask in Page1 and Page2 with different logic of processing.
Hope this will helpfull for someone.
You should make sure that you respect the guidelines for creating and initializing the object:
To ensure that your application receives the result of the
PhotoChooserTask, the object must be declared with class scope
within the PhoneApplicationPage class and you must call the chooser
constructor and assign the Completed event delegate within the page’s
constructor.
Source
Related
I have a Xamarin form map on my screen and I'm using PropertyChanged event to retrieve geolocation information from my server and display the proper pins on screen.
While coding the solution I noticed the PropertyChanged event is triggered multiple times (up to 10 times) with a single zoom or drag action on the map. This causes unnecessary calls to server which I want to avoid.
Ideally I want to make only one call to server when the final PropertyChanged event is called but I cant's find an easy solution to implement this.
At this point I've added a refresh button to my page that becomes enabled when a PropertyChanged event happens and I disable it after user uses the button.
Obviously this fixed the too many calls to server but made the solution manual.
I was wondering if there is a more elegant way to make the server call but do it automatically.
Thanks in advance.
I just test the PropertyChanged event on iOS side and it just triggered one time with a single zoom or drag action on the map.
While if it really triggered multiple times, you can use a timer to call the server when the final PropertyChanged event is called, for example:
public partial class MapPage : ContentPage
{
Timer aTimer;
public MapPage()
{
InitializeComponent();
customMap.PropertyChanged += CustomMap_PropertyChanged;
}
private void CustomMap_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (aTimer != null)
{
aTimer.Enabled = false;
aTimer.Stop();
aTimer.Close();
}
aTimer = new Timer();
aTimer.Interval = 1000;
aTimer.Enabled = true;
aTimer.Elapsed += ATimer_Elapsed;
aTimer.Start();
}
private void ATimer_Elapsed(object sender, ElapsedEventArgs e)
{
aTimer.Stop();
//do web request
Console.WriteLine(sender);
Console.WriteLine("CustomMap_PropertyChanged");
}
}
In the above code, I set the Interval = 1 second, that means in 1 second, whatever how many times PropertyChanged triggered, only the last call will trigger the ATimer_Elapsed function.
The Interval can be set to any value depending on your requirement.
We've got a Xamarin.Forms Android app in which we're displaying progress on a loading page, the progress value being sent by an event from another class.
We're using FreshMvvm which has ViewIsAppearing and ViewIsDisappearing overrides available in the PageModel.
So we're subscribing on ViewIsAppearing, and unsubscribing in ViewIsDisappearing - we're also unsubscribing in a PrepareForDispose method which is intended to ensure the PageModel has cleaned up so that it can be disposed.
Code is below. ProgressManager is supplied by IoC
protected override void ViewIsAppearing (object sender, EventArgs e)
{
base.ViewIsAppearing (sender, e);
ProgressManager.ProgressEvent += ProgressManager_ProgressEvent;
}
protected override void ViewIsDisappearing (object sender, EventArgs e)
{
base.ViewIsDisappearing (sender, e);
RemoveEventHandlers();
}
public override void PrepareForDispose()
{
RemoveEventHandlers();
base.PrepareForDispose();
}
private void RemoveEventHandlers()
{
ProgressManager.ProgressEvent -= ProgressManager_ProgressEvent;
}
The problem is that, when examining object in Profiler, we can see the LoadingPageModel is still in memory, because of the EventArgs created in the ViewIsAppearing (examining the "Paths To Root" in Profiler tells us this).
When I log/debug the app, I can see that RemoveEventHandlers has been called.
So is _ProgressManager.ProgressEvent -= ProgressManager_ProgressEvent;_ failing to remove the handler, or is there another reason that we've still got a reference to the PageModel from the EventArgs?
Edit One possibility is that we're subscribing more than once, but unsubscribing only once. I've checked with debug/logging, and I don't think this is the case. We're subscribing/unsubscribing symmetrically.
It turns out that we were subscribing twice (due to the lifecyle of the page in question at the start of the app lifecycle). Therefore the single unsubscribe was leaving a subscription behind.
Fixing this fixed the problem.
I quickly made a Windows Forms project which loads a GUI of different textboxes with float values. Some of them do have already a value initialized. All textboxes have to be updated after one of them is changed.
public Form1()
{
InitializeComponent();
initializeValues();
calculateValues();
}
public void initializeValues()
{
//textboxes are filled/initialized with default float values
}
public void calculateValues()
{
//here all textboxes are new calculated and updated
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
calculateValues();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
calculateValues();
}
Problem:
When I execute this project, it throws me a StackOverflowException which is unhandeled (infinite loop or infinite recursion). I think it's because during the calculateValues() method the text of the textBoxes will be changed and then the Eventhandlers are activated. That's the infinite loop :-(
How I have to change my code construct above to avoid this?
Thanks.
You should not using and calling "initializeValues();" (the cause of the infinite loop).
A first solution could be to put the init value of a TextBox in InitializeComponent :
MyTextBox.Text = myInitValue;
I solved the problem by changing the Event to "KeyPress". In this case, the Event is not activated by the method itself. No more infinite loops. Setting breakpoints and step through helped me to understand "the flow". Thanks CodeCaster.
I have the below event that gets fired upon geocoordinatewatcher object position changed event.
void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
//do the stuff here
}
Now when user clicks on any location on the map I want to call the above method and do the same stuff everytime.
Any idea how do I achieve this ?
Either call your event handler manually:
var position = new GeoPosition<GeoCoordinate>(DateTimeOffset.Now, new GeoCoordinate(32, 64));
this.watcher_PositionChanged(this, new GeoPositionChangedEventArgs<GeoCoordinate>(position));
Or rewrite your event handler to put the logic in another method, then call it:
void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
this.UpdatePosition(e.Position);
}
private void UpdatePosition(GeoCoordinate coordinates)
{
// Do the stuff here
}
This way, you just have to call UpdatePosition whenever you feel like it. I'd recommend this solution, it's way cleaner than the first one.
I would like to know if anyone has done this before or tried to do it. I would like to navigate from my current page to a page generated and stored on the isolated storage.
Is that possible?
I already found a way of generating the xaml code and I'm working on generating the xaml.cs file but I can't seem to find a way of navigating to the newly created and existing file in the isolated storage.
I am using the "isostore" URI schema but it throws an exception in RootFrame_NavigationFailed:
[System.InvalidOperationException] = {"No XAML was found at the location '/isostore;/screenTest.xaml'."} . Thank you in advance.
Best regards,
Cipri
I think the closest you can get is:
Store usercontrols (rather than pages) in the isolated storage
Load them using XamlReader.Load
Inject the loaded UserControl inside of the current page
Drawbacks:
You can forget about the code-behind file as you can't compile it. You'll have to find another way to wire-up the events. I suggest taking a MVVM approach, by binding actions and using the same viewmodel for every usercontrol
You're not using the NavigationService, so you have to handle the navigation stuff (back button and application resuming after tombstoning)
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
string UserName;
IsolatedStorageSettings.ApplicationSettings.TryGetValue<string>("UserName", out UserName);
if (!string.IsNullOrEmpty(UserName))
{
txtUserName.Text = UserName;
txtPassword.Focus();
}
else
txtUserName.Focus();
}
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
IsolatedStorageSettings.ApplicationSettings["UserName"] = txtUserName.Text;
}