Xamarin.ios: MFMailComposeViewController somewhat crashes when dismissed - c#

I found myself at a very strange problem. In the application we are developing, there is a feature to send the mail from the app itself.
According to Xamarin recipes, the MFMailComposeViewController is the way to go for the Xamarin.ios.
https://developer.xamarin.com/recipes/ios/shared_resources/email/send_an_email/
As it seems there is a problem with just some of the devices, however the pattern is to me unclear.
While pressing the button "Send" or Cancel, the Finished delegate is called. This part should normally dismiss the MailViewController.
On some of the devices the behaviour is as expected, the Mail controller is removed from the screen and the underlying controller is displayed.
On some devices however, the mail controller stays on top, and the app is not responding anymore. The debugger does not show anything.
Did anybody face this issue so far? Could this be somehow solved? I was reading some of the similar behavior in obj-c or swift code, however their solution did not help me.
MFMailComposeViewController in Swift does not dismiss
This is my code:
private void OnSendMailClick(object sender, EventArgs e)
{
if (MFMailComposeViewController.CanSendMail)
{
string receiptText = trx.isReversed ?
Utilities.GetTransactionAndRefundReceipt(trx, manager) : Utilities.GetReceipt(trx, true);
var mailController = new MFMailComposeViewController();
mailController.SetSubject(String.Format("Receipt number: {0}", trx.STAN));
mailController.SetMessageBody(receiptText, true);
mailController.Finished += OnSendResult;
PresentViewController(mailController, true, null);
}
}
and the Finished delegate looks like this:
private void OnSendResult(object sender, MFComposeResultEventArgs e) => e.Controller.DismissViewController(true, null);
Edit
It turns out the problem is in the inheritance of the MFMalComposeViewController, which is inherited by UINavigationViewController.
As I am already using an underlying UINavigationcontroller this causes sometimes problems. As soon as I find a suitable solution I will post it here as an answer.

The problem was solved. It turns out, that the problem lied in the nuget package I was using.
https://github.com/jdehlin/Xamarin-Sidebar/
From the version 1.9.4 the behavior is easily reproducible with an iPhone device.

Related

Issue with loaded Midi.Net DLL

Lately I'm having some issues in different applications that I have made. All of these applications use a Midi-controller to send midi-notes to a lighting desk. The issue is the same for all of these applications.
In runtime, when I'm working on the application, it sometimes occurs that my complete application freezes. I don't get any warningmessages, nor is the debugger popping up to tell me what's wrong. It always occurs when I want to play a midi-note. The only thing I can do at that point, is to reboot the entire machine, which is not that funny.
Because the application hangs and I don't get any debugging information, I'm certain it has to do with the DLL I use to send Midi-notes and that there's an issue there or in the way I have implemented the dll.
I've posted the code below and I would appreciate it, if someone could tell me what I'm doing wrong?
This is de code in the mainform initializing the Midi
MidiTools midi;
private void initMidi()
{
midi = new MidiTools();
midi.Enabled = true;
}
The initMidi() is called from inside the Form_Load-function.
The code to play a Midi-note is:
midi.playNote(22,0)
Below is the code inside the MidiTools-class file
using Midi;
namespace MidiTest
{
class MidiTools
{
public bool Enabled { get; set; }
OutputDevice outputDevice = OutputDevice.InstalledDevices[1];
Channel selectedChannel = Channel.Channel16;
int velocity = 127;
private void playNote(int noteNumber, int delay)
{
// CONVERT THE NOTE
Note selectedNote = (Note)noteNumber;
if (Enabled)
{
Thread.Sleep(delay);
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss NOTE: ") + selectedNote.ToString());
outputDevice.Open();
outputDevice.SendNoteOn(selectedChannel, selectedNote, velocity);
outputDevice.Close();
}
}
}
}
The Midi-library itself was downloaded from this link:
https://midi-dot-net.googlecode.com/files/midi-dot-net_src_1.0.5.zip
In the past I've tried multiple ways of fixing this problem. I've tried inserting a bigger delay, I've tried cueing the messages in a list and processing them one by one to prevent a midinote from being asked to play wile another note is still being sent, but none of those helped.
In 98% of the cases it works, it's just occasionally that it freezes on me.
I'm using the M-Audio Midisport controller. (http://www.m-audio.com/products/view/midisport-4x4-anniversary-edition) but it has also happened on other controllers.
So any help is greatly appreciated.
Best regards,
Kenneth

Is there any event triggered when a new window is added to the desktop

I want to know whether there is any event triggered when a new window appears/comes on the desktop. I am open to using COM,WMI,WinApis, UIAutomation or any other method but the language of choice is C#.
The actual requirement:
A process has 1 main window and many other windows. The class name of one of the windows is, say, X, (i got this info using pinvoke). Now this window pops up some times whenever there is some notification in the process. I do not want to show this window. I do not have code access to that process so that i can disable that window. So is there any way that i can get an event or any other mechanism which keeps track of the desktop and anytime a window with classname X comes/about to come it hides it.
Do tell if i am not clear with the question.
Thanks
EDIT : Simon's answer is really good. I tried that and am able to get notification for all windows except notifications/toast windows such as that of lync's im toast notification or outlook new mail notification. I tried with different elements of Automation Element and Windows Pattern but still could not get those...Any ideas how i can get those...you may read comments in Simon's answer for more context/detail. Once again thanks to Simon for introducing to the great power of UIAUtomation...Loving it!
As Damien said in his comment, you can use UI automation, like this in a C# sample console app:
class Program
{
static void Main(string[] args)
{
Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Subtree, (sender, e) =>
{
AutomationElement src = sender as AutomationElement;
if (src != null)
{
Console.WriteLine("Class : " + src.Current.ClassName);
Console.WriteLine("Title : " + src.Current.Name);
Console.WriteLine("Handle: " + src.Current.NativeWindowHandle);
}
});
Console.WriteLine("Press any key to quit...");
Console.ReadKey(true);
}
}
One option is RegisterShellHookWindow. You supply a window handle that can receive notification messages. The notifications that could be useful to you are HSHELL_WINDOWCREATED or HSHELL_WINDOWACTIVATED.
Here MSDN has provided code for registering for windows notifications. But this is specific to Windows Sever 2008. I think similar you can find for your version of Window.

Handle the event when device connect to cradle windows ce opennetcf in C#

I develop an application on windowCE 5.0 with opennetcf library.
I want to check WHEN my Device is connected to Cradle. It means I want to handle the event of plugged the device to cradle or other similar.
My purpose is that when Device is connected to Cradle, I disable all forms of my application,
and when it is removed from cradle, all the forms are enabled.
I search much. But the answer is not matched to my expect.
Please help me.
After reading reference of opennetcf, I found out the two events: ACPowerApplied and ACPowerRemoved
Here is my code:
public static event DeviceNotification ACPowerApplied;
public static event DeviceNotification ACPowerRemoved;
void Form1_ACPowerRemoved()
{
MessageBox.Show("Un-cradle");
}
void Form1_ACPowerApplied()
{
MessageBox.Show("Cradle");
}
private void Form1_Load(object sender, EventArgs e)
{
ACPowerApplied += new DeviceNotification(Form1_ACPowerApplied);
ACPowerRemoved += new DeviceNotification(Form1_ACPowerRemoved);
}
But the process did not step into Form1_ACPowerRemoved() and Form1_ACPowerApplied().
Is there any idea for that? Sorry for my poor English. Thank you in advance.
Your code is wrong. You've subscribed to the form's event, and nobody raise it.
Documentation doesn't show how-to-use code, I think. It shows declaraion.
Maybe it will work (not tested):
OpenNETCF.WindowsCE.DeviceManagement.ACPowerApplied += Form1_ACPowerApplied
OpenNETCF.WindowsCE.DeviceManagement.ACPowerRemoved += Form1_ACPowerRemoved
Also you can try to use WinAPI calls: http://blogs.msdn.com/b/davidklinems/archive/2005/02/10/370591.aspx
If you want, I have complete code, but there are a lot of waste and "OnRs232Connect" event.
By the way, what does "craddled" mean for you? Craddle can be disconneted from both AC and PC. I mean, do you want to handle when your device started to get electricity power, or when it started connecting to the PC via Active Sync? If the second, you want to catch "OnRs232Connect" event

C# BackgroundWorker skips DoWork and goes straight to RunWorkerCompleted

I'm new with C# so go easy on me!
So far - I have a console app that listens for client connections and replies to the client accordingly.
I also have a WPF form with a button and a text box. The button launches some code to connect to the server as a BackgroundWorker, which then waits for a response before appending it to the end of the text box.
This works great, once. Sometimes twice. But then it kept crashing - turns out that the DoWork block wasn't being called at all and it was going straight to RunWorkerCompleted. Of course, the .result is blank so trying to convert it to a string fails.
Is this a rookie mistake? I have tried searching the internet for various ways of saying the above but haven't come across anything useful...
This is the code so far: http://pastebin.com/ZQvCFqxN - there are so many debug outputs from me trying to figure out exactly what went wrong.
This is the result of the debug outputs: http://pastebin.com/V412mppX
Any help much appreciated. Thanks!
EDIT: The relevant code post-fix (thanks to Patrick Quirk below) is:
public void dorequest(string query)
{
request = new BackgroundWorker();
request.WorkerSupportsCancellation = true;
request.WorkerReportsProgress = true;
request.ProgressChanged += request_ProgressChanged;
request.DoWork += request_DoWork;
request.RunWorkerCompleted += request_RunWorkerCompleted;
request.RunWorkerAsync(query);
}
You're attaching your DoWork handler after calling RunWorkerAsync. Flip those around and that should fix it.
Also, in the future please paste code in your question rather than using an external site. And when possible give the smallest amount of code that demonstrates the problem. Makes it easier on us and people who might have the same issue.

Possible to download a file via WebKit browser in C# using webkitdotnet?

I'm using WebKitDotNet to simulate and automate a web browser. This is really nifty and works in most respects. However, when I try to implement this code, WebKit doesn't trigger a download:
WebKitBrowser _b = null;
private void button1_Click(object sender, EventArgs e)
{
_b = new WebKitBrowser();
_b.DownloadBegin += new FileDownloadBeginEventHandler(b_DownloadBegin);
_b.Error += new WebKitBrowserErrorEventHandler(_b_Error);
_b.AllowDownloads = true;
_b.Navigate("http://sourceforge.net/projects/webkitdotnet/files/WebKit%20.NET%200.x/0.5/WebKit.NET-0.5-bin-cairo.zip/download");
}
void _b_Error(object sender, WebKitBrowserErrorEventArgs e)
{
MessageBox.Show("error!");
}
void b_DownloadBegin(object sender, FileDownloadBeginEventArgs e)
{
MessageBox.Show("hi");
}
Neither the "Error" nor the "DownloadBegin" events fire. I would expect at least one of them to do so - is there a setting that I'm missing?
EDIT: I know this is an old question, but here's the update. When I wrote this question, I was trying to automate a process that required a human being - once per day - to log onto a website, provide credentials, and click a download link. We were hoping to be able to do this programmatically to relieve the monotony for the poor person tasked with doing this job.
Unfortunately, WebKitDotNet did not succeed in this task. Although, in a webkit based browser, you can click on the link and trigger a download, in the embedded WebKitDotNet clicking on the link did nothing. My guess is that something within WebKitDotNet lost the event. If anyone wants to test this, you can use the Sourceforge download link to test.
One of the guys on my team did eventually solve this problem by using an Internet Explorer automation tool called "IMacros". We selected this product because 1) We could guarantee that IE was installed on every computer that would run the program, and 2) IMacros could correctly receive the event from the website and trigger the file download.
On the Issue tracker there is a post date from March 24, 2011 in which is stated that download does not work yet:
https://github.com/webkitdotnet/webkitdotnet/issues/7
Since there are few issues in the tracker, it would have probably been marked as resolved if the feature was added meantime.

Categories

Resources