How do we handle simple public property setters in Command Pattern to make them undoable? Do I need to create a separate command for every property?
Details
My application (WPF/MVVM/C#) currently implements undo/redo functionality by maintaining a stack of "state snapshots". These snapshots are created upon every undoable action and pushed to the stack. While this approach has worked correctly so far, the size of undo stack keeps swelling, making application less responsive.
I'm now considering the prospects of moving to standard Command Pattern. Since I'm already using MVVM Light, I'd just extend RelayCommand to create UndoableRelayCommand and then push these to my undo stack instead of the snapshots. So far so good.
The problem however is that a lot of VM-level objects are bound directly to UI controls (through standard WPF Binding) and therefore get set directly without involving any RelayCommand. Setting of these properties needs to be an undoable action. How do I fit this requirement into standard Command Pattern, while keeping my Bindings intact?
I'd advise you to still copy values into the command, because otherwise older commands will go out of sync with the state of the binding at the moment when they happened.
I presume that you are already only taking the snapshot of the affected value, not the entire form (that would be a blunder).
I do not understand what does it mean that the application is becoming unresponsive. All operations on undo/redo stack should be O(1). If your implementation is more complex than O(1) then that might be the direction for you to investigate before redesigning the mechanism.
Anyway, with the undo/redo stack, there is one practical trick usually applied in larger applications. Bound the size of the stack. With more items pushed, let it "forget" the oldest ones. Another practical trick also used around is to purge the stack every time the state is persisted, and only keep the last command to redo. Those are the performance tweaks I saw this far.
Related
Using C# and Framework 4.5 I have designed a Windows Desktop app for an employer (I'm a private freelance) the application is receiving and analyzing litterally ton of data.
currently, the thread reading it, store the message in a hidden and disabled (enabled=false) ComboBox in order to avoid delay. another thread (Timer) remove the first item in ComboBox and store message in a Database and loop until there is nothign left in ComboBox.
Is there another way instead of ComboBox to store that Data (string) and remove "older" one
currently using
strMessage =cmbMessages.Items[0].ToString();
cmbMessages.Items.RemoveAt(0);
I thought about collection or dictionnary... collection is not fast and dictionnary... well... should it be used like that? (not better solution then ComboBox to my knowledge)
What you all think ?
First, you may want to leave the terms "police" and "monitoring" out of any questions or answers you post. There are people who may not help you on those grounds alone. Use terminology such as "my employer" and "security software" to avoid all that.
It's not exactly clear if you're using WPF or WinForms. Both have a property named Items. Please specify in future questions. There are sometimes different solutions available depending on what framework you're using.
As commenters have noted, your method of using the ComboBox as a storage object is unorthodox. It's usually problematic because simply touching UI elements may cause side effects(in this case possibly a layout pass and refresh). That's a lot of baggage.
The data flow you have described is best represented as a queue. Data comes in, data goes out, in the order it was added. Use a Queue if you're sure the data will only flow through one thread or a ConcurrentQueue if not. Periodically update the ComboBox from the queue and you're good to go.
On a different note, you should consider a different UI control. I can imagine navigating a ComboBox and seeing the options flow in and out of it being a pain to deal with. Perhaps a ListBox is more appropriate.
I'm working on a small standalone system in C# .Net running on an embedded processor, we're using GTK for the UI and storing the data in a MySql database. Database access is done through our own data access layer and we use our own translation layer to convert from Model types into DAO types.
For accessing data in the system we have a DataStore class for each type, this class holds an index list (Just Name and ID, we do lazy loading) of all active items and this is currently contained in an ObservableCollection which the UI binds to.
When we update this list we read the indexes from the DB, convert the items from DaoTypes to Model types and then enter them into the ObservableCollection.
The guy in charge of the UIs has just raised a Jira ticket saying that adding to the ObservableCollection this way is raising a Notify Property Changed event for each item we enter and that this makes it unusable for his UI.
I'm not sure if this is an issue with the way I do things by using the ObservableCollection or if the UI should be able to handle this level of load, we're not talking loads of items, maybe 20-50 maximum.
I tried maintaining this list on the fly, adding and removing items manually rather than loading the list each time but loading the list fresh is much more reliable.
Should we be able to expect the UI can handle these Property Changed Notifications?
Is there a more efficient way than using the ObservableCollection like this?
Without more specifics, or e.g. a good, minimal, complete code example that clearly illustrates the question, it's impossible to provide advice with any real confidence.
That said:
Should we be able to expect the UI can handle these Property Changed Notifications?
That depends on the UI and your platform. For a desktop computer, 50 insertions into a UI object is nothing. For an embedded platform, it could be an issue. It could be disastrous for a UI written naively and targeting an e-paper display (i.e. a display with a painfully slow refresh rate).
Note that if you did want to push this issue back onto the UI code, and the UI is for some reason unable to process 50 separate updates, it could instead keep a timer and update the UI after the collection has been modified only when no modifications have occurred for some time (e.g. 100 ms…or whatever delay would be appropriate in your scenario, depending e.g. on the latency of whatever framework you're using, the latency of your own code, etc.).
Is there a more efficient way than using the ObservableCollection like this?
The whole point of ObservableCollection<T> is so that the consumers of the collection can be notified of changes to the collection as they occur. This is common and very useful in e.g. the WPF scenario. There is no way to disable this behavior.
Note that if you are not necessarily tied to ObservableCollection<T> per se, you could use instead the BindingList<T> class. That has a RaiseListChangedEvents property, which you can set to false to disable notification.
But even if ObservableCollection<T> had such a feature, or you were able to switch to BindingList<T>, then you would have a different problem: how to signal to the UI that you are done adding elements to the list. And since you would have to solve that, you could just implement that anyway and just use any collection type (since such a mechanism should work with any collection type).
The UI is binding to the ObservableCollection
What binding implementation are you using? Something built into .NET? If so, which one? Something else?
Note that any of the .NET binding implementations would correctly handle the scenario where the entire collection is replaced with another, whether that happens by setting a UI property to the collection directly, or that UI property is itself bound to a bindable property (e.g. supported by XXXChanged, INotifyPropertyChanged, or is an actual DependencyProperty in e.g. WPF or Winrt).
In other words, if you are using a binding implementation with "reasonable" behavior, then the suggestion to just populate a whole new list and reset the bound collection to that new list should work fine. When the UI sees the collection object reference value change, it can rebuild the UI accordingly based on the new collection object.
I will point out that since you seem to recognize the value in reliability on your end with respect to reloading a new collection vs. maintaining a single collection as edits occur, I would think you would similarly recognize the value in doing so with respect to the UI code.
I.e. even if there weren't a performance problem, if you're going to rebuild the list yourself anyway based on the DB contents, doesn't it make sense to just give the UI that whole new collection as well? It's certainly easier, and any theoretical performance gain that might be had by updating the UI as insertions and deletions occur is lost by your layer, which apparently groups such edits into a single large-scale update operation.
I have a running order for 2 handlers Deleting and Reordering pictures and would like some advises for the best solution.
On the UI some pictures are deleted, the user clicks on the deleted button. The whole flow, delete command up to an event handler which actually deletes the physical files is started.
Then immediately the user sorts the remaining pictures. A new flow from reorder command up to the reordering event handler for the file system fires again.
Already there is a concurrency problem. The reordering cannot be correctly applied without having the deletion done. At the moment this problem is handled with some sort of lock. A temp file is created and then deleted at the end of the deletion flow. While that file exists the other thread (reordering or deletion depending on the user actions) awaits.
This is not an ideal solution and would like to change it.
The potential solution must be also pretty fast (off course the current one is not a fast one) as the UI is updated thru a JSON call at the end of ordering.
In a later implementation we are thinking to use a queue of events but for the moment we are pretty stuck.
Any idea would be appreciated!
Thank you, mosu'!
Edit:
Other eventual consistency problems that we had were solved by using a Javascript data manager on the client side. Basically being optimist and tricking the user! :)
I'm starting to believe this is the way to go here as well. But then how would I know when is the data changed in the file system?
Max suggestions are very welcomed and normally they apply.
It is hard sometimes to explain all the details of an implementation but there is a detail that should be mentioned:
The way we store the pictures means that when reordered all pictures paths (and thus all links) change.
A colleague hat the very good idea of simply remove this part. That means that even if the order will change the path of the picture will remain the same. On the UI side there will be a mapping between the picture index in the display order and its path and this means there is no need to change the file system anymore, except when deleting.
As we want to be as permissive as possible with our users this is the best solution for us.
I think, in general, it is also a good approach when there appears to be a concurrency issue. Can the concurrency be removed?
Here is one thought on this.
What exactly you are reordering? Pictures? Based on, say, date.
Why there is command for this? The result of this command going to be seen by everyone or just this particular user?
I can only guess, but it looks like you've got a presentation question here. There is no need to store pictures in some order on the write side, it's just a list of names and links to the file storage. What you should do is to store just a little field somewhere in the user settings or collection settings: Date ascending or Name descending. So you command Reorder should change only this little field. Then when you are loading the gallery this field should be read first and based on this you should load one or another view. Since the store is cheap nowadays, you can store differently sorted collections on the read side for every sort params you need.
To sum up, Delete command is changing the collection on the write side, but Reoder command is just user or collection setting. Hence, there is no concurrency here.
Update
Based on your comments and clarifications.
Of course, you can and, probably, should restrict user actions only by one at the time. If time of deletion and reordering is reasonably short. It's always a question of type of user experience you are asked to achieve. Take a usual example of ordering system. After an order placed, user can almost immediately see it in the UI and the status will be something like InProcess. Most likely you won't let user to change the order in any way, which means you are not going to show any user controls like Cancel button(of course this is just an example). Hence, you can use this approach here.
If 2 users can modify the same physical collection, you have no choice here - you are working with shared data and there should be kind of synchronization. For instance, if you are using sagas, there can be a couple of sagas: Collection reordering saga and Deletion saga - they can cooperate. Deletion process started first - collection aggregate was marked as deletion in progress and then right after this reordering saga started, it will attempt to start the reordering process, but since deletion saga is inprocess, it should wait for DeletedEvent and continue the process afterwards.The same if Reordering operation started first - the Deletion saga should wait until some event and continue after that event arrived.
Update
Ok, if we agreed not touch the file system itself, but the aggregate which represents the picture collection. The most important concurrency issues can be solved with optimistic concurrency approach - in the data storage a unique constraint, based on aggregate id and aggregate version, is usually used.
Here are the typical steps in the command handler:
This is the common sequence of steps a command handler follows:
Validate the command on its own merits.
Load the aggregate.
Validate the command on the current state of the aggregate.
Create a new event, apply the event to the aggregate in memory.
Attempt to persist the aggregate. If there's a concurrency conflict during this step, either give up, or retry things from step 2.
Here is the link which helped me a lot some time ago: http://www.cqrs.nu/
My question is how programmers create, code, and organize subforms in general. By subforms, I mean those groups of controls that make up one UI experience. I'm looking for hints to help me better organize my form codes and to speed up the process of creating such forms. I swear to God, it takes way too long.
I've identified three broad groups of subform elements:
-Subforms have commands to do something.
-Subforms have data elements to carry out those commands.
-Subforms have states used to track things that aren't data.
The approach I use is to focus on what it takes to perform the commands which will determine which data elements are needed and how they should be validated.
Also, do programmers use check lists when creating forms?
p.s. I program as a hobby.
This is incredibly fuzzy. There is however a red flag though, you seem to be talking about UI as a starting point instead of the end result. That's a classic trap in winforms, the designer is rather good and makes it way too easy to endlessly tinker with form layouts. You forever keep adding and removing controls and event handlers as your ideas about how the program is supposed to work evolve.
This is backward and indeed a huge time sink. Effective design demands that you grab a piece of paper and focus on the structure of the program instead. The starting point is the model, the M in the MVC pattern. As you flesh out how the model should behave, it becomes obvious what kind of UI elements are necessary. And what commands should be available to the user.
The V emerges. Instead of jumping into the designer, sketch out what the view should look like. On paper. Make a rough draft of an organized way to present the data. And what operations are available to the user to alter them. Which selects the type of controls and the menus and buttons you'll need. Once that congeals, you can very quickly design the form and add the C. The event handlers that tie the UI to the model.
There's a very interesting tool available from Microsoft that helps you to avoid falling into this trap. I love the idea of it, it intentionally makes the UI design step imperfect. So you don't spend all that time pushing pixels around instead of focusing on the design of your program. It draws UI designs in a paper-and-pencil fashion, there are no straight lines. Incredibly effective not just for the programmer, also a "keep the customer focused and involved" fashion. So that the customer doesn't fall in the same trap either, nagging about a control being off by one pixel. It is called SketchFlow, link is here. It is otherwise the exact same analogue of paper and pencil, but with a 'runs on my machine' flourish.
Try CAB I'm not sure you should use it, but the pattern will help you understand how to write your gui layer in a good way.
I was thinking of centralizing this functionality by having a single method that gets passed an AppState argument and it deals with changing the properties of all GUI elements based on this argument. Every time the app changes its state (ready, busy, downloading so partially busy, etc), this function is called with the appropriate state (or perhaps it's a bit field or something) and it does its magic.
If I scatter changing the state of GUI elements all over the place, then it becomes very easy to forget that when the app is in some state, this other widget over there needs to be disabled too, etc.
Any other ways to deal with this sort of thing?
Emrah,
Your idea is good. You need to limit the state structure and this is the only way to ensure reliable UI. On the other hand do not follow the "one function" idea to strictly. Rather continuously follow its direction, by creating a function and then do progressively refactoring all attributes to a single "setter" function. You need to remember about a few things on your way:
Use only one-way communication. Do not read the state from controls since this is the source of all evil. First limit the number of property reads and then the number of property writes.
You need to incorporate some caching methodology. Ensure that caching does not inject property reading into main code.
Leave dialog boxes alone, just ensure that all dialog box communication is done during opening and closing and not in between (as much as you can).
Implement wrappers on most commonly used controls to ensure strict communication framework. Do not create any global control framework.
Do not use this ideas unless your UI is really complex. In such case using regular WinForms or JavaScript events will lead you to much smaller code.
The less code the better. Do not refactor unless you loose lines.
Good luck!
Yes, this is the most time consuming part of the GUI work, to make a user friendly application. Disable this, enable that, hide this, show that. To make sure all controls has right states when inserting/updateing/deleteing/selecting/deselecting things.
I think thats where you tell a good programmer from a bad programmer. A bad programmer has an active "Save"-button when there is nothing changed to save, a good programmer enables the "save"-button only when there are things to save (just one example of many).
I like the idea of a UIControlstate-handler for this purpose.
Me.UIControlStates=UIControlstates.EditMode or something like that.
If having such object it could raise events when the state changes and there we put the code.
Sub UIControlStates_StateChanged(sender as object, e as UIControlStateArgs)
if e.Oldstate=UIControlStates.Edit and e.NewState=UIControlStates.Normal then
rem Edit was aborted, reset fields
ResetFields()
end if
select case e.NewState
case UIControlStates.Edit
Rem enalbe/disable/hide/show, whatever
Case UIControlStates.Normal
Rem enalbe/disable/hide/show, whatever
Case UIControlStates.Busy
Rem enalbe/disable/hide/show, whatever
Case Else
Rem enalbe/disable/hide/show, whatever
end select
end sub
#Stefan:
I think we are thinking along the same lines, i.e. a single piece of code that gets to modify all the widget states and everyone else has to call into it to make such changes. Except, I was picturing a direct method call while you are picturing raising/capturing events. Is there an advantage to using events vs just a simple method call?