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.
Related
I am trying to have some logic when Windows user is being changed while my UWP app is running and for that in my OnLaunchApplicationAsync method I have:
var userWatcher = Windows.System.User.CreateWatcher();
userWatcher.AuthenticationStatusChanged += AuthenticationStatusChanged;
and I also have
private void AuthenticationStatusChanged(Windows.System.UserWatcher sender, Windows.System.UserChangedEventArgs args)
{
// Some logic
}
But the problem is that when I log off with my current user and sign in with another one, the expected event is not being raised.
I have also tried out userWatcher.Updated for updating user data as well as userWatcher.AuthenticationStatusChanging with the same result.
Am I doing this in a wrong way?
You need to start the watcher, otherwise these events are not fired.
I've run into this several times. My app receives some event (e.g. WndProc) and needs to return quickly. The code that needs to run takes some time, and does not need to be executed before returning from the event handler.
My current solution is to start a timer for a short time, and in the Tick event - run that code.
But that seems like the wrong tool for this case, and is prone to some errors (like running the code more than once, for example).
So, is there any ExecuteWhenThisThreadIsIdle scheme?
EDIT
A C#/.NET solution would be best, but a framework specific solution would be welcome too. Mainly Winforms. (But also WPF, UWP, Xamarin.Forms, ...)
The code needs to run on the same thread as the event handler. (Usually the UI thread.)
In WinForms, you can subscribe to Application.Idle.
For example ...
private bool _wndProcEventHooked = false;
protected override void WndProc(ref Message m) {
// Run your code here
}
private void Application_Idle(Object sender, EventArgs e) {
if (!this._wndProcEventHooked) {
// Hook your wndProc event here.
this._wndProcEventHooked = true;
}
}
In WPF this can be done using DispatcherTimer:
var timer = new DispatcherTimer
(
TimeSpan.FromMinutes(10),
DispatcherPriority.ApplicationIdle,// Or DispatcherPriority.SystemIdle
(s, e) => MessageBox.Show("Timer"),
Application.Current.Dispatcher
);
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.
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.
I just had VS generate an event handler for me, and it created a property instead of a method. I don't understand that. I just tried a separate test in VS 2012, and it worked as expected.
First, this is my test that worked as I thought it would:
private static void EventTest()
{
Geek skeet = new Geek();
skeet.SomeEvent += skeet_SomeEvent;
}
When I had VS generate the handler for me, it created this.
static void skeet_SomeEvent(object sender, EventArgs e)
{
throw new NotImplementedException();
}
That makes sense. That method will be called when the event is invoked.
Now, the problem... I'm working on an existing project, in VS 2010, and when I do the same thing (have VS generate the handler):
private void SubscribeToPlcDataChangeEvents()
{
_plc.PlcLoggerEventHandler += _plcLoggerEventHandler;
}
It creates a property:
public EventHandler<PlcLoggerEventArgs> _plcLoggerEventHandler { get; set; }
Why? I don't get that. I want to handle the event in a method.
EDIT - This is how the event handler is declared:
public event EventHandler<PlcLoggerEventArgs> PlcLoggerEventHandler;
If you hit Tab twice you will notice that it is generated "properly" in cases of event handlers.
In the case where you use the "Options to help bind the item" shortcut Alt+Shift+F10 in Visual Studio 2010, your two possible actions in this case are:
Generate property stub for 'PlcLoggerEventHandler' in ...
Generate field stub for 'PlcLoggerEventHandler' in ...
So, the fact that a property is then created when you use this seems to be By Design, even though in the case of an event handler it makes no sense.