I am using Xamarin Forms (Xamarin Studio Community) to write an iOS app. I just need to capture the coordinates of user touch and release on a button.
I have searched all over Google, and I only found responses that simply did not work. They were either for Android, or Swift, or XCode, or WAY too much to make practical use of.
The closest I've seen are answers that say "There is currently no way to do that in Xamarin Forms." Which seems absurd to me because it seems like one of the most basic, fundamental things a programmer would need.
All I need is to capture the x,y from where the user touches and releases. Here are my handlers all ready to go.
thisHereButton.TouchDown += (object sender, System.EventArgs e) =>
{
//pressed
touchX = [x];
touchY=[y];
};
thisHereButton.TouchUpInside += (object sender, System.EventArgs e) =>
{
//released
releaseX = [x];
releaseY=[y];
};
That's it. If someone could provide a simple, practical answer, that would be great!
EDIT: With a bounty goes additional research, in hopes that someone can help.
I followed the advice in the comments and after some analysis, have determined that this is the chunk of code that is most relevant.
private bool touchStartedInside;
public override void TouchesMoved(NSSet touches, UIEvent evt)
{
base.TouchesMoved(touches, evt);
// get the touch
UITouch touch = touches.AnyObject as UITouch;
if (touch != null)
{
//==== IMAGE TOUCH
if (backdrop.Frame.Contains(touch.LocationInView(View)))
{
//TouchStatus.Text = "Touches Moved";
}
//==== IMAGE DRAG
// check to see if the touch started in the drag me image
if (touchStartedInside)
{
// move the shape
float offsetX = (float)(touch.PreviousLocationInView(View).X - touch.LocationInView(View).X);
float offsetY = (float)(touch.PreviousLocationInView(View).Y - touch.LocationInView(View).Y);
txt_sizeValText.Text = "" + offsetY;
//DragImage.Frame = new RectangleF(new PointF(DragImage.Frame.X - offsetX, DragImage.Frame.Y - offsetY), DragImage.Frame.Size);
}
}
}
That is taken directly from their example. Right there in the code, it gives me what I'm looking for, as well as the bonus of the "offset" which is what I really need in the end.
So I've got this void in my code and the code still compiles, so there are no errors.
The only thing I cannot figure out is how to make use of this void. How do you call it?
If I have to use a different handler than the ones in my original post, that's fine. Whatever you can tell me about how to make this work...
You don't need to call the TouchesMoved() method. It is automatically called when the Objective C runtime calls it ( it is an override of the method to be called) - It is basically the handler of the native event. You can already get the offsets, and you can raise your own events inside that method to change your button. It is already done.
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 trouble figuring out how to remove listener for cloud function which is triggered every few minutes. I have the following code:
void InitializeFirebase() {
FirebaseDatabase.DefaultInstance.GetReference ("Main").ValueChanged += ListenForServerTimestamp;
}
void OnDisable() {
FirebaseDatabase.DefaultInstance.GetReference("Main").ValueChanged -= ListenForServerTimestamp;
}
The issue is that the even is still registered even when Unity is not running. Ie play button is turned off, it is still registering the events. I must be doing something wrong with removing the events, but after looking through all other answers, i cant figure out what is the issue.
Thanks.
Edit: If there is some way to disconnect Firebase in Unity, that would be also something i could try. But i cant again find anything anywhere on disconnecting Firebase in Unity.
My top suggestion will be to cache your database reference in the script where you're retrieving it. Something like this:
DatabaseReference _mainRef;
void InitializeFirebase() {
_mainRef = FirebaseDatabase.DefaultInstance.GetReference ("Main");
_mainRef.ValueChanged += ListenForServerTimestamp;
}
void OnDisable() {
if(_mainRef != null) {
_mainRef.ValueChanged -= ListenForServerTimestamp;
_mainRef = null;
}
}
If you inspect GetReference, you'll see something like this in ILSpy:
public DatabaseReference GetReference(string path)
{
return new DatabaseReference(this.internalDatabase.GetReference(path), this);
}
So you may be removing the listener on an object other than the one you register it on.
A few other things to double check. I'd recommend you do this on a MonoBehaviour rather than a ScriptableObject. Since you mention events getting triggered when the play button isn't selected, I expect that this is happening in Editor. ScriptableObject generally doesn't behave the way I'd expect in Editor and can cause odd issues around play/pause.
If it is on a MonoBehaviour, I would recommend that you not place it on one that has the [ExecuteInEditMode] attribute. You can also get odd behavior if you're invoking some of these calls from an Editor script (CustomEditor, PropertyDrawer, &c).
I don't think any of these (other than the ref) are your issue. But it's a few more things to look at.
I hope this helps!
--Patrick
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 have this piece of code
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode== Keys.Z)
{
BarTimer.Value = 0;
timer1.Start();
timer1.Interval = 500;
BarTimer.Minimum = 0;
BarTimer.Maximum = 80;
}
}
And it works just fine, but I want to be able to press it when in a fullscreen application, so I can see the progress bar on my second monitor. Is there a property or something i can change to make it work like that?
If it's a single key you can use RegisterHotKey. There is sample code in this answer: how to use RegisterHotKey and the one linked in it. The Microsoft C++ documentation is here.
If you want to intercept all keyboard input you would need a keyhook. I suggest you google WH_KEYBOARD_LL and SetWindowsHookEx. But I don't think you can do this in c#; I've only ever seen key hooks written in C/C++. They will also cause some firewalls to take an interest - intercepting all keyboard input can be considered potentially hostile.
Hi I know of a nice tutorial I found On code project.
It worked for me when i needed something like this.
http://www.codeproject.com/Articles/19004/A-Simple-C-Global-Low-Level-Keyboard-Hook
Regards,
I am hoping someone can help me this problem... or can clarify what I am doing wrong...
I am dynamically adding event handlers to an event.
This works very well for Controls that comes with XAML, but not for my own events. I found out that in WinRT events returns a EventRegistrationToken. According to this link "add" should return a token.
My problem is that all events that I implement only returns void.
I created multiple projects (Win 8 WinRT, Win 8.1 Universal, Win 10 Universal) already to find out what I am doing wrong. Every project are showing the same problem. I googled hours... and every implementation I found are stating that "add" requires a return object.
My questions are:
Do someone know if this is a bug?
If not a bug... Is there something I have to set or change so that my events are returning a token?
If events are behaving like they should on your environment, can you please provide me with a test project so that I can so a compare. Maybe this has something to do with project settings or type.
edit: finally I can add an image...
PS: I also posted my code for the dynamic event handling on pastebin (code of DynamicEventHandler)
In your code,
var method = this.GetType().GetRuntimeMethods().First(x => x.Name == "ExecuteCommand")
The ExecuteCommand is a .NET method rather than the Windows Runtime method, why do you use "GetRuntimeMethods"?
Here is the code works on my side.
public MainPage()
{
this.InitializeComponent();
var runtimeEvent = this.myButton.GetType().GetRuntimeEvent("Click");
var handlerMethodInfo = this.GetType().GetMethod("OnClick");
var delegateHandler = handlerMethodInfo.CreateDelegate(runtimeEvent.EventHandlerType, this);
Func<Delegate, EventRegistrationToken> add = (a) => {
return (EventRegistrationToken)runtimeEvent.AddMethod.Invoke(this.myButton, new object[] { a });
};
Action<EventRegistrationToken> remove = (a) => { runtimeEvent.RemoveMethod.Invoke(runtimeEvent, new object[] { a }); };
WindowsRuntimeMarshal.AddEventHandler(add, remove, delegateHandler);
}
public void OnClick(Object sender, RoutedEventArgs e)
{
}