C# detect if calls were in the same UI action - c#

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...

Related

Labview .Net events

I have a .Net 4 control /.dll which I am using with LabVIEW.
The control exposes the following event:
public delegate void CommNewDataEventHandler(UInt16 u16StageGroup, UInt32 u32Status , string [] strNewDataTitle, float[] fNewData, string[] strNewDataUnit);
public event CommNewDataEventHandler CommNewDataEvent;
What I would like to do is subscribe to this event within LabView and update a numeric indicator with the value specified in float[] fNewData.
What is the correct way to do this?
current VI callback VI
There is no "correct" way to do this, but you can put code in the callback VI to pass data to where you need it.
For example, you can pass the control reference as the user parameter (this is the terminal on the register node and the control on the FP) and then use Variant to Data to convert it back to a reference (edit - you don't need to convert if you create the VI after wiring the data into the node) and use the value property. This is inelegant, but it will work.
A more elegant solution would be to pass a user event of your data type to the callback VI (for instance, as the user parameter) and then generate that event with the data you got. This is more cumbersome, but less hidden.
Like so (ignore the missing horizontal wire. It must have blinked when I took the screenshot, but it's there):
You can find the image here if imgur takes it down: https://forums.ni.com/ni/attachments/ni/130/16266/1/event%20callback%20example.PNG
As the previous poster has suggested, there is no "correct" way to do this. There are a number of different approaches you might take depending on the scope of your project. For the general .NET event registration and handling procedure NI has a good example here: https://decibel.ni.com/content/docs/DOC-9161
This sample code is a "timer handler" (using a native .NET timer API) and illustrates how to register for an event and create your callback VI. Let's modify this to achieve your goal. To do so, we must somehow communicate through our callback VI to another part of the program (containing the numeric indicator we want to update). Options for establishing communication between seperate parts of our application:
Global variables
Functional global variable
Control/indicator references
Structured synchronization mechanism (i.e. queue, notifier, etc.)
Messaging system (i.e. UDP via local loopback, managed queues, etc.)
There are many, many options and this is certainly not an exhaustive list. Every approach has advantages and disadvantages and your decisions should be based on what kind of application you are writing. Note that some are better style than others. My preference (when writing fairly simple application) would be to use something like a notifier for a single point data update. My opinion is that this offers a good amount of flexibility/power and you won't get knocked for style points.
Below is a modified version of NI's example program using a notifier to pass the data from the callback VI to the top level VI. When the event fires, the callback pushes some data onto the notifier to signal to the top level VI that the elapsed time has expired and the event has occured. The top level VI waits for the notification and uses the provided data to update the value of the numeric indicator.
Note that this is a very trivial example. In this case I don't really even have to send any data back. I know that if the notifier does not timeout that the event has fired and can subsequently increment my counter in the top level. However, the notifier allows you the flexibility to stuff arbitrary data in the communication pipe. Hence, it can tell me "hey! your condition occurred!" and "here's some data that was generated".
Callback VI
Top Level VI
If you are writing a larger application, your loop to monitor the notifier can run in parallel with other code. Doing so allows you have an asynchronous mechanism for monitoring the status of the event and displaying it on the GUI. This approach allows you to monitor the event without interfering with the rest of your application.

How to run events sequentially in C# or Similar Frameworks

How to Cancel/Regulate event which is executing in parallel with same event in another thread.
For e.g. In a textbox, every time we enter a character the event fires if text changed event is defined. But after entering first character, the event (Let us call First Event) takes lot of time (as there will be more strings which match a single character), and does some action like changing content of a title label. And after entering a second character the new event which raised to run in parallel takes less time. So now, the second event which fired after entering second character executes fast and returns first and first event executes last and thus, first event's result will be printed ultimately on the label rather than the second one.
Is there a better way to cancel the first event before starting the second event. One thing that comes to my mind is to register threads on a global list variable and kill all threads which are not dead before starting your execution. Will this work?? Any better way to handle this situation.
P.S. I know that search could be initiated after a space or enter to solve this particular issue. But I think you have already noticed my main point. :)
My favourite library for dealing with this exact problem is Rx.Net with TPL. This behaviour can be easily implemented with a combination of a Cancellable Task with an event observer using Observable.FromAsync
Some code!
var textChanged = Observable.FromEventPattern(x => textBox.TextChanged += x, x => textBox.TextChanged -= x)
.Select(_ => textBox.Text);
IDisposable eventHandler = textChanged.Throttle(TimeSpan.FromMilliseconds(500))
.Select(text => Observable.FromAsync((TaskCancelationToken cancel) => DoSearchTaskAsync(text, cancel)))
.Switch()
.Subscrible(results =>
{
//Update the UI
});
Note there is no need to explicitly type any of this...I am only doing it for clarity, but I am more than likely to have mistyped a class name or two...
EDIT
The Search method would be the method body of Task<TReturn> DoSearchTaskAsync(string, TaskCancellationToken).
The magic sauce comes from the Observable.FromAsync and Observable.Switch.
Each time we have a change in the textBox.Text we fire an event. That is filtered by the .Throttle (as you would expect). The clever bit is when we then create a new event source on DoSearchTaskAsync using Observable.FromAsync. At this point we have an IObservable<IObservable<TResult>>, or another way to put it, an eventsource of an eventsource. The switch means we only want the results from the most recently sent eventsource from the outter eventsource, and kill (Dispose) the subscription of previous eventsources.
The act of disposing the previous Observable.FromAsync will cause the TaskCancellationToken to cancel, and prevent its results bubbling up, whilst we subscribe to the new Task.
All very clever stuff, and I only recently came across this AWESOME pattern (I would credit the author if I could).
As for the Observable.FromEventPattern that is pretty unfortunate, as of C#5, there are no first class eventhandlers, so we pass in a lambda for subscription and a lambda for de-subscription.
The .NET Task API has the concept of cancellation built in. See this page for an example and links to more information. http://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

Can't get my head around implementing an Undo/Redo functionality, should I use a Stack?

I'm getting kind of confused right now, having one of those days I guess.
I need to implement an Undo and Redo functionality for a form. For simplicities sake, let's say that I only save the control which was modified and the value it had when it left Focus.
How do I save this information in a way that lets me go back or forth in the 'timeline'.
I thought about using a Stack, but while I was testing my little demo, I had a mild aneurysm and here I am.
Code needed, not really but would help. I'm more interested in the algorithm I'd need to implement. Any suggestions?
Yes, you would use a stack. There are a couple ways to do it; read these references:
http://en.wikipedia.org/wiki/Command_pattern
http://en.wikipedia.org/wiki/Memento_pattern
Each has its pros/cons.
A stack is perfect if you push a "change" onto it, and when undo pop a "change" from it. You then push that popped change into another stack representing redo. At some point in the future, hopefully on save, you clear both stacks.
It's not actually as simple as that, as you need to record the type of change, understand the old and new values etc. So when you pop from the undo stack, the thing you pop must describe what the prior value was and what control it was set to.
Inverse for the redo stack, it needs to understand what the new value was and where it went. But yes, the idea of two stacks is a good start for a homebrew undo-redo.
A good example of a business object based undo is CSLA.NET, which has UndoableBase:
http://www.lhotka.net/cslanet/
http://www.koders.com/csharp/fidCF6AB2CF035B830FF6E40AA22C8AE7B135BE1FC0.aspx?s=serializationinfo
However this records a snapshot of an object's state, so it would be more advanced that your form-based concept. However, CSLA.NET offers full data binding support so a data bound object inheriting from UndoableBase would naturally support undo (not redo) in the UI.
I would use an IUndoableAction interface. The implementations could store whatever data they needed to be done and undone. Then yes, I would use a Stack to hold them.
interface IUndoableAction
{
void Do();
void Undo();
}
Stack<IUndoableAction> Actions;
Each kind of action would implement the Do and Undo methods.
Then, somewhere there would be these two methods:
void PerformAction(IUndoableActionaction)
{
Actions.Push(action);
action.Do();
}
void Undo()
{
var action = Actions.Pop();
action.Undo();
}
As for what to store in the action classes, some actions could just store the old value. However, once I had an action to swap two rows in a spreadsheet. I didn't store the values of every cell in both rows -- I just stored the row indices so they could be swapped back. It could be easy to fill up tons of memory if you stored all of that state for every action.
Then you want a Redo stack as well, and when you undo an action it is pushed onto the redo stack. The redo stack will need to be cleared when a new action is performed, so things don't get out of order.
Probably the most straightforward is to have the undo/redo stack combination.
An alternative is to have an array or list of actions, and just increment/decrement a pointer to an index in the array. When an action is undone, the index is moved back by one, and when the action is redone, the index is moved forward by one.
The advantage here is that you don't require a pop-and-then-push sequence for each action.
Things to consider:
If you undo several times, and then perform an action, all of the
redo actions must be eliminated.
Make sure you check the boundaries and ensure that there is an action available to undo/redo before trying to perform the undo/redo.

Best way to implement Filewatching in my case?

So, this is roughly how my C# program looks
Main()
// call to method that reads XML file and loads it into a list of structure
// call to method that works on the structure, manpulates data etc.
// call to method that starts filewatching
Filwatching_method()
// if any change is detected, calls method OnChange
OnChange()
// Action on change
If OnChange method is called i.e. a change has been detected, I want to repeat the entire process all over again. Should I call Main() from OnChange, or is there another way that is better?
You may take a look at the FileSystemWatcher class which allows you to monitor and be notified of events happening on the file system like file being changed.
Personally, this is what I think.
Yes, you should call your Main from your OnChange method, if that is in fact what you want to do (i.e., just run Main again).
But to prevent uncontrolled recursion, you should ensure that the file manipulation you're performing from within Main does not itself trigger OnChange. This could be by either setting a flag or temporarily removing your Changed handler and adding it back when you're done.
Create one FileSystemWatcher object, which throws several events, you can handle every event differently.

Order of Precedence with methods?

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!

Categories