I'm trying to add share functionality to my Windows Phone App. The code behaves in an unpredictable way. Sometimes it works, but mostly it doesn't and I haven't been able to get any details about what's causing the crash. Could someone please go through the code below and let me know if I've missed something? Thanks!
public ArticlePage()
{
this.InitializeComponent();
//..
RegisterForShare();
}
private void RegisterForShare()
{
DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager,
DataRequestedEventArgs>(this.ShareLinkHandler);
}
private void ShareLinkHandler(DataTransferManager sender, DataRequestedEventArgs e)
{
DataRequest request = e.Request;
DataRequestDeferral defferal = request.GetDeferral();
request.Data.Properties.Title = this.article.Title;
request.Data.Properties.Description = this.article.Summary;
request.Data.SetWebLink(new Uri(this.article.UrlDomain));
defferal.Complete();
}
private void ShareCommand_Click(object sender, RoutedEventArgs e)
{
DataTransferManager.ShowShareUI();
}
UPDATE
The code always works while I'm debugging from visual studio but pretty much never otherwise. I made a release build thinking there might be some code in the debug build which is causing the problem but that didn't make any difference.
I also had that problem recently. The share UI crashes when one of the important parameters is not set. In your case I'd suspect that
this.article.UrlDomain
is null or not a valid Uri pattern. You should build an if-clause around it and make sure that you're dealing with a real Uri. To test your code you should insert hardcoded constants and run it again. If it doesn't crash, check your Title, Summary and UrlDomain one by one.
Other places to investigate:
Try adding your handler in the OnNavigatedTo method and remove it when you're leaving the page
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested += SharePage_DataRequested;
}
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
DataTransferManager.GetForCurrentView().DataRequested -= SharePage_DataRequested;
}
I also searched my code and looked at official samples again and did not find any defferals. Just to be sure - if I were you I'd strip all unnessecary lines in my code and get it as closest as possible to the official examples and then extend it back to where it was from there which is why I would comment out these two lines as well:
void SharePage_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
DataRequest request = e.Request;
//DataRequestDeferral defferal = request.GetDeferral();
request.Data.Properties.Title = this.article.Title;
request.Data.Properties.Description = this.article.Summary;
request.Data.SetWebLink(new Uri(this.article.UrlDomain));
//defferal.Complete();
}
Okay, I had the same problem. ShowShareUi actually suspends your app. If you try suspending your app you would get the error. It is actually the serialization problem.
If you want to look into the error, then while debugging, press the lifecycle events and suspend, you will crash in debug mode now.
If you are navigating between pages with a custom class you would get error. *My suggestion is that you would convert to jsonstring and send and get it back.*
I've faced similar problem (crash on ShowShareUI).
After very long investigations I've found, that this appears because unhandled exception in SaveFrameNavigationState (SuspensionManager class from template project).
In my case it was because SessionStateForFrame method failed on parsing class that couldn't be serialized.
Check out what you're saving in page state on SaveState of the page.
It happens not only on ShowShareUI but in suspend mode generally.
Related
Before to start the question, I would like to inform that I am completely newbie to Xamarin...
I would like to understand what I need implement/add/edit in my solution in my project in order to get
private void canvasView_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
being called by:
public ColorDemo()
{
// some code suppressed here, but not related to the question
SKCanvasView canvasView = new SKCanvasView();
canvasView.PaintSurface += canvasView_PaintSurface;
canvasView.InvalidateSurface();
}
The solution (Visual Studio 2022) runs ok in my smartphone and/or emulator but the event handler is never called. I tried many things, but no success. I would like to understand the reason why the event handler is never called.
I have a basic Winform app (.Net 4.6) where the main Form consists of only one docked panel. The form acts as the screen manager and will change the screen by adding/removing custom UserControls to/from the panel.
To put it simply, I have a button in the processing screen where if you click on it, will trigger a simple callback:
private void langButton_Click(object sender, EventArgs e)
{
ActionCallback?.Invoke(UserAction.BackToTitle);
}
This will call a method in the main form and eventually:
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");
Now I have checked that the CurrentUICulture changes as expected but as soon as it goes back to the UserControl, which is after the invoke line, the CurrentUICulture magically reverts back to whatever it used to be before executing the delegate! (no other code changes the culture)
What's even more baffling is similar code for my title screen works fine.
They both run on UI thread.
I have been searching online and also tried many things including locking the line that is changing the culture in case the value was cached or something but no luck.
Obviously a lot of code is omitted but that's the gist of it. I could purposely pass the culture back and assign it again but that would just be bad.
Anyone could shed some light on this behaviour and possibly suggest some solutions?
EDIT 1:
I think I have finally found the issue. The callback was something like this:
private async void HandleUserAction(UserAction action)
{
switch (action)
{
case UserAction.BackToTitle:
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");
break;
//other cases omitted
}
}
I basically did a quick test and extracted this to another anonymous function but without the async :
screen.ActionCallback2 += (a) => { System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");};
and it finally works!
I am not sure if it is duplicate of the post below as I am already using .Net 4.6 or above but I have to do some more reading.
Keep CurrentCulture in async/await
I won't answer my own question yet as I am still trying to grasp why this is happening, if anyone else can explain this, feel free to do so.
EDIT 2:
I found that the issue can be reproduced with the code below
private async void button16_Click(object sender, EventArgs e)
{
//will revert back to previous value once it exits the function
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("jp");
}
private void button15_Click(object sender, EventArgs e)
{
//it will be changed to jp
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("jp");
Task.Run(() =>
{
this.Invoke((MethodInvoker)delegate
{
//this will be changed back to jp after exiting the thread, even though its same UI thread
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");
});
});
}
In the end I fixed it by adding this to my app.config
<AppContextSwitchOverrides value="Switch.System.Globalization.NoAsyncCurrentCulture=true" />
Though it is still a little strange to me especially when the function button15_Click doesn't involve async.
I have poked around here to try and find a resolved issue to help me solve my problem. Unfortunately I don't know enough about C# and Forms/Services to be able to interpret many of the answers, so I thought I'd post my issue here, in it's uniqueness, and see if I can get a sufficient answer.
I recently got an internship for a local company, learning C# and SQL to manage their shipping/inventory logistics.
I have gotten pretty good at creating windows forms with VisualStudios2017, and my knowledge of Java helps me pick up C# pretty quickly.
However, recently I was given the task of developing a Windows Service, which will run in the background, and do some repetitive task every minute or so.
Since I am familiar with the "Drag and Drop" techniques of adding features to windows forms, My supervisor suggested I use a Timer in my service, so, that's what I did, I did a "Drag and Drop" to add the timer component to my service, and renamed it "timerMainTick"
Here is My code. I want to start simple, all this code does is move to some local directory (henceforth referred to as $DIR), create a folder $DIR/GabbServiceDir, and make a text file $DIR/GabbServiceDir/AnotherTest.txt". However, every time the timer ticks, it is supposed to create (if it does not already exist) a new text document "$DIR/GabbServiceDir/Test.txt" and append the date-time to it every 2.5 seconds. This does not happen.
namespace GabbService
{
public partial class GabbService : ServiceBase
{
public string dir = "../../Users/Tyler/GabbServiceDir";
public GabbService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
Directory.CreateDirectory(dir);
timerMainTick.Interval = 2500; //miliseconds = 2.5seconds
File.AppendAllText(dir + "/AnotherTest.txt","asdiofbhjasdflikjbasdf\r\n");
timerMainTick.Enabled = true;
timerMainTick.Start();
}
protected override void OnStop()
{
}
private void timerMainTick_Tick(object sender, EventArgs e)
{
timerMainTick.Enabled = false;
File.AppendAllText(dir + "/Test.txt", DateTime.Now.ToString() + "\r\n");
timerMainTick.Enabled = true;
}
}
}
And a picture of the directory and it's contents after the service was started.
This is in Powershell, in $DIR/GabbServiceDir
PS C:\Users\Tyler\GabbServiceDir> ls
Directory: C:\Users\Tyler\GabbServiceDir
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 6/23/2017 9:54 PM 72 AnotherTest.txt
PS C:\Users\Tyler\GabbServiceDir> cat .\AnotherTest.txt
asdiofbhjasdflikjbasdf
timerMainTick is Windows.Forms.Timer, and many of the solutions provided indicate to use a different kind of timer, the System.Timers.Timer.
This is all well and good, and may fix my problem, but the issue comes when trying to do something when this new type of timer ticks. When I double click the Windows.Forms.Timer in the Service Designer, it automagically writes a bunch of source, and gives me a method to begin writing code in, that magically executes when the timer ticks. I am not yet familliar with all of the magic that is going on in the backround, because I've only begun to learn C# as of the day I got this internship. I don't know what to name the methods for custom objects so that the "backround magic" will work, thus I am unable to interperate some of the solutions provided for problems similar to mine.
Perhaps someone could enlighten me.
For instance. Say I go into the Designer Source Code, and add a component
private System.Timer.Timer timerSystemTimer;
Then, in the Service source code and alter the method that was previously
private void timerMainTick_Tick(object sender, EventArgs e)
To
private void timerSystemTimer_Tick(object sender, EventArgs e)
I get an error immediately:
The more reading I do the more I see lots of event handlers being passed around and I have yet to comprehend what they do. Perhaps what I need is a link to some good literature. I am capable of looking for this on my own but I imagine many people here may have links to other bits of good literature more specific to what I want to comprehend here.
*Something I have found so far that may be useful to people in my situation:
https://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx
Error in VS - You added timerSystemTimer but did not remove timerMainTick component which still references timerMainTick_Tick as handler of it's Tick event. Compiler does not find this handler method anymore since you changed it to timerSystemTimer_Tick.
Adding different timer - Never modify designer file code. You could add a System.Timers.Timer instance to your class code, instantiate it in OnStart and provide handler for Elapsed event. Here's a sample for you.
please mind I'm still a beginner:
I am creating a program with windows forms in c#. However, after i had some sync issues the main form loader does not seam to be working. I checked the code with my limited knowledge but i can't seem to find anything wrong?
Here's the code (mainfrm.designer.cs:1):
...
this.Name = "frm_Main";
this.Load += new System.EventHandler(this.frm_Main_Load);
this.menuStrip1.ResumeLayout(false);
...
And here is my loader (mainfrm.cs)
private void frm_Main_Load(object sender, EventArgs e)
{
Everything i do here does not get executed.
}
Does anyone see the problem?
This is indeed a bug within Visual Studio, as mentioned by Hans.
stackoverflow.com/a/4934010/17034
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am new to coding in C#, and am making a little program to scrape the current Bitcoin value from Mt.Gox.
Here is the code I am currently using:
namespace BitcoinValueScraper
{
public partial class GetValue : Form
{
public GetValue()
{
InitializeComponent();
}
private void GetValue_Load(object sender, EventArgs e)
{
System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
wb.Navigate("www.mtgox.com");
wb.Stop();
wb.Document.GetElementById("lastPrice").SetAttribute("value", textBox1.Text);
}
}
}
This returns with:
"An unhandled exception of type 'System.NullReferenceException'
occurred in BitcoinValueScraper.exe Additional information: Object
reference not set to an instance of an object."
Help please!
You have to bind to the LoadCompleted Event on the webbrowser control. If you dont do this, document on the control will be null. The page might not be downloaded yet.
Example Code:
public WebBrowser webb;
public MainWindow()
{
InitializeComponent();
webb = new WebBrowser();
webb.LoadCompleted += webb_LoadCompleted;
webb.Navigate("http://www.google.com");
}
void webb_LoadCompleted(object sender, NavigationEventArgs e)
{
//NOW DOCUMENT SHOULD NOT BE NULL
MessageBox.Show("Completed loading the page");
mshtml.HTMLDocument doc = webb.Document as mshtml.HTMLDocument;
mshtml.HTMLInputElement obj = doc.getElementById("gs_taif0") as mshtml.HTMLInputElement;
mshtml.HTMLFormElement form = doc.forms.item(Type.Missing, 0) as mshtml.HTMLFormElement;
}
Above is for windows presentation foundation webbrowser control. In windows forms i believe the event is: DocumentCompleted reference: http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser%28v=vs.110%29.aspx
Here is windows forms code (i just tested this):
private System.Windows.Forms.WebBrowser wb;
public Form1()
{
InitializeComponent();
GetValue_Load(null, EventArgs.Empty);
}
private void GetValue_Load(object sender, EventArgs e)
{
wb = new System.Windows.Forms.WebBrowser();
wb.DocumentCompleted += wb_DocumentCompleted;
wb.Navigate("http://www.google.com");
}
void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
MessageBox.Show("Document loading completed");
//GET YOUR DOCUMENT HERE
}
While not a direct answer to the code problem you're currently encountering I'd like to highly suggest that you try doing things a different way because trying to pull information out of HTML on a website like that is extremely fragile (if they change their markup at all your code is broken) and just wrong on a lot of levels. In general, programmers usually rely on data APIs for querying this kind of information as it provides a standardized and (hopefully) tested way of querying for information. A quick Google search turned up some Bitcoin API's offered by BlockChain who seem to be pretty well regarded in the bitcoin world. Here is a sample API call to query for Bitcoin exchanges rates:
http://blockchain.info/api/exchange_rates_api
By making an HTTP request to their API you can much more reliably pull down the information that you're looking for and display it in your user interface.
Further Bitcoin API resources can be found here:
http://blockchain.info/api
Unfortunately, as you are new to both programming and interacting with APIs its hard to give you an answer without taking the time to physically write the code for you. However, I can say that currently, your approach is wrong. A WebBrowser object is not a suitable mechanism with which to interact with a web API. A more suitable approach would be to make an HTTP call to the API URL that you posted and then read the JSON out of the response. This would then need to be parsed into some kind of format that makes sense for your application (such as a simple Price object etc). There are many articles online regarding parsing JSON with C# as well as interacting with web based APIs through the HTTP protocol. I'd definitely recommend that you start there.
Here is a great starting article that will walk you through creating a basic application for interacting with JSON APIs. Just replace the Bing URLs with the appropriate BitCoin ones and you should have a good starting point.
If anything try:
namespace BitcoinValueScraper
{
public partial class GetValue : Form
{
System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
public GetValue()
{
InitializeComponent();
}
private void GetValue_Load(object sender, EventArgs e)
{
wb.Navigate("www.mtgox.com");
wb.DocumentCompleted += wb_LoadCompleted;
}
void wb_LoadCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
HtmlDocument doc = wb.Document;
textBox1.Text = doc.GetElementById("lastPrice").ToString();
}
}