In Flash 10 there are methods that require that they are triggered from user-initiated actions like button click, keyboard up/down keys, etc.
Is it possible to implement this behaviour in .NET? For example, if we have this subroutine:
void SomeMethod() {
// Here some stuff
}
how to check inside it whether the method was called from a mouse click event handler?
Also we can think of this methods like the protected functions in World of Warcraft, if anyone knows what I mean.
EDIT: Looks like this behaviour is implemented in Silverlight — we can popup file dialogs (open, save) ONLY by mouse click or other user-initiated action, otherwise a SecurityException will be thrown. I want to achieve this bevaviour but in my case it’s not a file dialog but our own methods.
Why not just provide it as a parameter?
void SomeMethod(bool userInitiated) {
// Here some stuff
}
Given that you're already calling it, sometimes from an event handler and sometimes not, you already have that information.
EDIT: Another approach is to have a thread-static field which you set on entry to an event-handler and then reset on exit (in a finally block). Any code which wants to test whether they're "responding to a user action" can then test that field.
If that's not good enough, then I suspect the answer is simply "no".
EDIT: You can get at the call stack (see the StackTrace class) but that's relatively slow and can miss out stack frames due to inlining. There's also Code Access Security which may just about help you - but I doubt it.
It seems that you are writing some sort of plugin API. You want to provide a method that does something the user might not want, e.g. changes the clipboard contents, and you want to ensure that your plugins can call that method only in response to a user action.
The only way I can think of to do this is that the API needs to be continually aware of whether it is currently processing a user-initiated action or not. Presumably there will be some code in your program that calls the plugin-provided code, e.g.
if (plugin.HasHandlerForMouseClick)
plugin.HandleMouseClick();
At this point you will need to remember that this is a user-initiated action. Once the method returns, that’s the end of the user-initiated action:
if (plugin.HasHandlerForMouseClick)
{
_userInitiated = true;
try
{
plugin.HandleMouseClick();
}
finally
{
_userInitiated = false;
}
}
Then, in your “unsafe” method, e.g. the one to set the clipboard, you will have to check this flag:
public void SetClipboard(object newValue)
{
if (!_userInitiated)
return; // or throw AccessDeniedException?
// set clipboard here
}
As hinted by Jon, the field should be declared thread-static. This means that there is a separate copy of the field for each thread:
[ThreadStatic]
private static bool _userInitiated = false;
Related
Here: http://msdn.microsoft.com/en-us/library/hkkb40tf(v=VS.90).aspx, it says that, to call a button's click event from another button, you can/should do it this way:
button1.PerformClick();
However, in my situation (VS 2003. NET 1.1), this doesn't compile (admittedly, the link above specifies VS 2008, but it does not have a link to the pertinent info for prior versions, as msdn often does).
This compiles:
private void btnPrint_Click(object sender, System.EventArgs args)
{
if (this.recordChanged)
{
//btnSave.Click();
btnSave_Click(sender, args);
}
. . .
...but I don't know if it's THE way to do it.
Put the business logic that you want to execute in a separate method (e.g. DoSave()), and then your event handlers can both just call that internal method rather than calling each other directly.
"Faking" events by calling the event handler methods directly is ugly and can lead to bugs (any programmer modifying the event handler in future may be unaware that it could be called under different conditions than expected/documented, which could cause the print option to behave strangely or even crash when it tries to do a save operation)
Also there is a good chance that you may want to cause a save operation from somewhere else in future - so it's always a very good idea to keep the business logic separate from the use interface that activates it.
I would do btnSave.Click(sender, args);. Here's the page on MSDN: http://msdn.microsoft.com/en-us/library/aa645739(v=VS.71).aspx
I have some nice, working edit-undo functionality in my winforms application. It works using a CommandStack class, which is two Stack<IStateCommand>s (one for undo, one for redo). Each command has an Execute and an Undo method, and the CommandStack object itself has an event that is fired when the stacks are changed.
The CommandStack also works out if the LogCommand method is called from its own Undo function, and therefore adding it to the redo stack, rather than the undo stack. This is done by simply adding the current ManagingThreadId to a List<int> object, then removing it after the Undo command is completed (as opposed to using the stack trace, which I believe would be much slower and a bit dirty).
There is a lot of different commands within my application so this formula is sort of set in stone as it'll take me a few days to redo all those IStateCommands implementations.
The only problem with this, currently, some UI events within also call other UI events, both of which log an IStateCommand to the undo history. Is there any way in C# that I can detect if the LogCommand function has already been called from the same UI event (Click, DragDrop, SelectedIndexChanged, TextChanged, etc), then I can combine the commands into one command (using my CommandList class, which also inherits IStateCommand)?
I've thought of saving the current time when the undo event was called, then if the next command is logged less than x milliseconds later, combine them in the history, but this seems a bit sloppy. I've also considered searching the stack trace, but I don't really know what to look for to find the root UI event, nor do I know whether I would tell the different between one button click, then a different click on the same button.
It may also be helpful to know that all of these commands are being called from the UI thread from event handlers (mostly from events from custom user controls). The only part of my application that uses another thread runs after most UI events, after the undo history is logged.
Thanks!
Sort Version
The same method is being called twice from the same UI event (eg, MouseUp, DragDrop). The second time this method is called, how do I check that it has already been called once by the same UI event?
Edit: The solution (sort of)
It's a bit of a dirty one as I don't have the time to completely re-write this system. However I've implemented it in such a way that gives the option not to be so dirty in the future.
The solution is based on one of Erno's comments on his answer (so I will mark his answer as accepted), where he suggests added a parameter. I added another overload to my LogCommand(IStackCommand) method in the CommandStack class, LogCommand(IStackCommand, string). The string is the actionId, which is stored for each command, and if this string is the same as the last, the commands are combined. This gives the option to go through each event and give a unique ID.
However, the dirty part - to get it working before we have to show the client, the actionId defaults to System.Windows.Forms.Cursor.Position.ToString(), ouch!! Since the cursor position is not changed while the UI thread is executing, this combines each command. It actually even combines TextChanged commands (as long as they don't move their mouse!)
It might be an option to add a local stack of called-commands to a command.
When a command executes other commands add the command to the local stack so you can undo the commands on this local stack when the command must be undone or redone.
EDIT
I am not quite sure what you don't understand.
I would simply add a CommandList property to the StateCommand. Everytime the StateCommand invokes/triggers another StateCommand it should add the new StateCommand to the CommandList. So the global CommandList keeps track of the Commands that can be undone from the UI and each StateCommand keeps track of the StateCommands it invoked (so these are not added to the global undo CommandList)
EDIT 2
If you can't or do not want to change to that setup you would have to pass a parameter to the execution of the commands that links them together.
Did you try to inspect the method stack and analyze it method-by-method:
StackTrace st = new StackTrace();
for ( int i=0; i<st.FrameCount; i++ )
{
StackFrame sf = st.GetFrame(i);
MethodBase mb = sf.GetMethod();
// do whatever you want
}
I don't know what you need exactly to achieve, but I implemented something similar, maybe you can get some ideas...
In summary, you can store some information in a ThreadStatic variable. Then, any time you want to log a command, inspect the thread static variable to find out the context in which you are logging the command. If it's empty, you are starting a new command logging sequence. If not, you are inside a sequence.
Maybe you can store the entry event (e.g. Click, DragDrop,...), or the command itself... It depends on your needs.
When the initial event callback is completed, clean the static variable to signal that the sequence has been completed.
I successfully implemented a similar strategy to track commands executed upon an object model. I encapsulated the logic within an IDisposable class that also implemented the reference counting to handle the nested usings. The first using started the sequence, subsequents using statements increased and decreased the reference counting to know when the sequence was completed. The outermost context disposing fired an event containing all the nested commands. In my specific case it has worked perfectly, I don't know if it may fulfill your needs...
I've got an XNA project that will be drawing several objects on the screen. I would like the user to be able to interact with those items. So I'm trying to build a method that checks to see which object the mouse is over, out of those which is the top most, and then fire an OnClick event for that object.
Checking for the things above is not the problem, but where to actually put that logic is most of the issue.
My initial feeling is that the checking should be handled by a master object - since it doesn't make sense for an object, who ideally knows only about itself, to determine information about the other objects. However, calling OnClick events remotely from the master object seems to be counter-intuitive as well.
What's the best practice in this situation?
Thanks,
Tyler
Don't put the logic in the event handler. Instead have the event handler call another method, passing the clicked object as argument:
// inside the OnClick event handler
ActOnObject(clickedObject);
Then you can call the same method anywhere else in the code, for any object:
ActOnObject(GetObjectUnderMouse()):
I would probably have something like an "ObjectManager", a class that would hold a collection of the objects and would handle the finding of the current object that should be clicked upon, and then call the click function on that object. Since the object itself isnt handling the click (it could but in my example technically the overall game itself, or possibly the ObjectManager is the one that catches the click) then i would just take the object that you want to click on and call something like
Object.Click(whatever parameters are logical for your situation)
in the end I think I am suggesting a very similar approach as Fredrik, however the main difference is I personally prefer the "Object" to know what should be done with the click, and thus call the function on the object itself - which might be what you would do in the function suggested above as well...
Well , for graphical objects (textures , sprites or the kind ..)
public MyObject()
{
....
public AreTheseMyCoordinates(int X, int Y);
}
Where , you get the screen coordinates of the mouse position.
Or you can make a Helper Class:
public static MouseHelper
{
public static IsObjectClicked(MyObject obj, int X , int Y)
{
....
}
}
I`d go with the static helper.
Say I have 2 methods. One is an method triggered by the selected index changing in the listbox. The second method helps by clearing all textboxes, setting listbox index to -1, and setting the focus.
Question:
Method two executes, during the code it changes the selected index of the listbox to -1, thereby setting off the event trigger for the 1st method. Does Method 2 HALT it's own execution and transfer the process to the event, and then return back to its work after Method 1 is finished... OR does method 2 finish its entire codeblock then transfer to Method 1 since the selected index changes?
The first case.
Let's leave threads out of it for a moment, particularly because they're not involved in your scenario.
You're talking about properties and methods, but underneath it all, it's all just functions. When one function invokes another, control in your program transfers to the called function. When that function finishes running, control returns to the point where it was called. Your program automatically remembers where it needs to go back to, no matter how deeply functions call more functions.*
When your second function sets the index, what really happens is that the compiler translates the property-set operation into a function call. (Properties are ultimately just "syntactic sugar" for functions.) That function calls a bunch of other functions that aren't important to the scenario, except that one of them is the one that invokes the "index changed" event handler. It sees that you have a method associated with that event, and it calls your first method.
Your first method runs, and when it finishes, it returns to the "invoke the index-changed event handler" function. Eventually, that and all the other unimportant functions finish running (perhaps after making more function calls in sequence), and the "set the index property" function returns control to your second method.
You can prove to yourself that your first suggestion is how it works. Display a message box in your first method, and display another message box after the point in your second method where you set the index property. (Use different messages!) You should see the first message appear, and after you dismiss the message box, you should see the second message appear, thus showing that the second method did not continue executing while the first one was running.
* There is a limit, but it's rarely hit unless there's a bug in your program. When you have too many nested function calls, what happens is a stack overflow.
There's a third alternative you can explore: they can also run at the same time! If I understand your question correctly, method 2 would be triggered by the index change event. In a C# Windows Forms application, this other event would occur in a separate thread of execution.
Concepts to explore: threading.
I hope this gives you a starting point in your explorations of knowledge.
Assuming no multi-thread situation, the event will fire before he end of execution of the method. If you want to see this, code what you have suggested in a .NET language and examine the Il produced. You can do this with ILDASM, or Reflector, or even create your own relfletion application. You do have to understand the syntax of IL enough to see the branch, but it is not that difficult, as long as you understand programming concepts.
Rob has labeled this "syntactical sugar", which I will agree with somewhat. It is really a compiler trick, but I guess it falls under the label "syntactical sugar" as it is commonly used.
I assume the language in question is c# and you thus have a language that supports multiple threads. If you don't want to worry about threads (which would be a bad idea if you consider user experience) you can run your GUI in one thread and have the same behavior, unless the components create their own thread (which would be a bit weird though). If you want to achieve an asynchronous (parallel) execution of the event you need to have the the event triggering in its own thread.
To answer your question: if you aren't using multiple threads, the method triggered by the event will be queued. This is exactly what happens when you see GUI responding slowly in some programs.
Hope it cleared things out and welcome from another newcomer :)
I myself am a beginner, maybe I can help. Method2 would fire, then when the selection changes, Method1 would do his stuff, then Method2 would continue.
If you don't want Method1 to fire at that time, you might want to do is something like:
(REALLY pseudo code)
Method2(object sender, System.EventArgs e)
{
//Unsubscribe Method1 from ListboxEvent
Listbox.OnSelectionChange -= Method1;
... Stuff Method2 actually does ...
Manualy call Method1 if you want it to fire
//Subscribe Method1 from ListboxEvent
Listbox.OnSelectionChange += Method1;
}
It's probably not optimal (and maybe some Best Practices...) but for a lack of a better explanation, at least you have a bit of information to help you search. Hope it helps!
if a condition occurs i have to stop the execution of the current method call and return to the state before the method call .how can i do it .. suppose a i am executing some sample method and a condition occurs and i am prompting a message box and then i want to return to state before this function call
If I'm understanding you correctly, you wish to undo changes you have made to certain variables if some condition is true? If that's the case, you will want to store a copy of all your variables (or your class as a whole). Then, if your condition comes up true, you'll have to revert all those variables to their initial state before returning from your function. It would be something like this:
// In order to clone your variable, you may need to inherit from
// ICloneable and implement the Clone function.
bool MyFunction(ICloneable c)
{
// 1. Create a copy of your variable
ICloneable clone = c.Clone();
// 2. Do whatever you want in here
...
// 3. Now check your condition
if (condition)
{
// Copy all the attributes back across to c from your clone
// (You'll have to write the ResetAttributes method yourself)
c.ResetAttributes(clone);
// Put a message box up
MessageBox.Show("This failed!");
// Now let the caller know that the function failed
return false;
}
else
{
// Let the caller know that the function succeeded
return true;
}
}
A generic rollback functionality on the heap is for me unheard of. But you can use the Command pattern to get undo functionality and use it for rolling back:
http://en.wikipedia.org/wiki/Command_pattern
Essentially you encapsulate an operation in an object that stores enough information of the change that it can undo it. You push that object onto a stack, and when your condition occurs, you go pop all command objects from the stack and undo them. Without more information about your case it's difficult to give more specific information or tell whether this is applicable for you.
Is it an error condition that could have been checked before calling the method? If so, throw an exception.
Otherwise, return something meaningful (e.g. if it's a void function, change it to return a bool, and return false).
This is what exceptions are for. You throw an exception to terminate the function and any caller, until an exception handler is reached.
Note that this should only be done if something exceptional has occurred; exceptions shouldn't be used as a "different kind of" return value, as they are more costly in terms of code size (whether thrown or not) and running time (if thrown) , than normals returns.
As far as returning to the state you had before, this is possible if your code and any library code through which the call proceeded was written in an exception safe manner.
I guess you are talking on the lines of object transactions OR transactional memory.
The least you can do is you can record the state (assignments) of the object being modified and write the old values on it when the condition to assignment fails.
Another solution, differing slightly from those above:
Check for the specified condition a bit now and then in your sample method.
public void MyMethod()
{
some code
if (conditionOccurred == true){ reset to the previous state and exit;}
more code
}
This is probably not according to the book, but it gives quite simple and readable code if you don't use it too often.
I probably don't have to mention that you need save the program's state if you want to be able to return to it, and you need to write some code that returns you to this state.
You can use the Memento pattern to implement object rollback. From here ...
The caretaker is going to do something
to the originator, but wants to be
able to undo the change. The caretaker
first asks the originator for a
memento object. Then it does whatever
operation (or sequence of operations)
it was going to do. To roll back to
the state before the operations, it
returns the memento object to the
originator.
Once you receive the event that indicates that you should roll back, you can undo the change and return to the caller. Here is some info. and links on why you should not use Thread.Abort.