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?
Related
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.
I'm writing a Mafia (Werewolf)-style game engine in C#. Writing out the logic of an extended mafia game, the model:
A Player (Actor) has one or more Roles, and a Role contains one or more Abilities. Abilities can be Static, Triggered, or Activated (similar to Magic the Gathering) and have an "MAction" with 0 or more targets (in which order can be important) along with other modifiers. Some occur earlier in the Night phase than others, which is represented by a Priority.
MActions are resolved by placing them in a priority queue and resolving the top one, firing its associated event (which can place more actions on the queue, mostly due to Triggered Abilities) and then actually executing a function.
The problem I see with this approach is that there's no way for an MAction to be Cancelled through its event in this mechanism, and I see no clear way to solve it. How should I implement a system so that either MActions can be cancelled or that responses with higher Priorities end up executing first/delaying the initial MAction?
Thanks in advance. I've spent quite some time thinking (and diagramming) this through, can't quite get over this hurdle.
Would it be possible to implement a cancellation stack that is checked by each MAction function and only executes if the MAction you are trying to execute is not in that stack. That way any time an action is popped it would only do something if it wasn't canceled already.
The situation as I understand it:
You have a series of things that happen with complicated rules which decide the order of what happens, and the order of what happens decides the quality/magnitude of the effect.
First things first, in order to make your life easier I'd recommend you limit your players to making all their moves before action resolution takes place. Even if this model is abandoned later it should make it easier for you to debug and resolve the actions. This is especially true if later actions can undo the effects of earlier actions like in the following example:
Dave transforms to a werewolf because he triggers the Full Moon ability. Then with werewolf powers he jumps over a wall and bites Buffy. Before Buffy dies she activates her time reverse ability and kills Dave before he jumps over the wall.
Regardless, your dilemma makes me think that you need to use a rules engine like NRules1, or implement your own. The primary goal of the rules engine will be to order/discard the stuff that happens according to your business logic.
Next you put these actions into a queue/list. The actions are applied against the targets until the business rules tell you to stop (Werewolf Dave died) or there aren't any more actions to apply. Once you stop then the results of the battle/actions are reported to the user.
There are other ways to accomplish your goals but I think this will give you a viable pathway towards your end goal.
1: I've never used this library so I don't know if it is any good.
In my plugin I have a code to check the execution context Depth to avoid infinite loop once the plugin updates itself/entity, but there are cases that entity is being updated from other plugin or workflow with depth 2,3 or 4 and for that specific calls, from that specific plugin I want to process the call and not stop even if the Depth is bigger then 1.
Perhaps a different approach might be better? I've never needed to consider Depth in my plug-ins. I've heard of other people doing the same as you (checking the depth to avoid code from running twice or more) but I usually avoid this by making any changes to the underlying entity in the Pre Operation stage.
If, for example, I have code that changes the name of an Opportunity whenever the opportunity is updated, by putting my code in the post-operation stage of the Update my code would react to the user changing a value by sending a separate Update request back to the platform to apply the change. This new Update itself causes my plug-in to fire again - infinite loop.
If I put my logic in the Pre-Operation stage, I do it differently: the user's change fires the plugin. Before the user's change is committed to the platform, my code is invoked. This time I can look at the Target that was sent in the InputParameters to the Update message. If the name attribute does not exist in the Target (i.e. it wasn't updated) then I can append an attribute called name with the desired value to the Target and this value will get carried through to the platform. In other words, I am injecting my value into the record before it is committed, thereby avoiding the need to issue another Update request. Consequently, my changes causes no further plug-ins to fire.
Obviously I presume that your scenario is more complex but I'd be very surprised if it couldn't fit the same pattern.
I'll start by agreeing with everything that Greg said above - if possible refactor the design to avoid this situation.
If that is not possible you will need to use the IPluginExecutionContext.SharedVariables to communicate between the plug-ins.
Check for a SharedVariable at the start of your plug-in and then set/update it as appropriate. The specific design you'll use will vary based on the complexity you need to manage. I always get use a string with the message and entity ID - easy enough to serialize and deserialize. Then I always know whether I'm already executing the against a certain message for a specific record or not.
I'm learning some C# and in the tutorials, they usually put most of the code on the button clicks for the sake of teaching. For example, if they were going to show a streamreader, they would do:
StreamReader sr = new StreamReader();
..inside the button's click function.
Is this a bad programming habit? From javascript, I remember reading a warning on some code I wrote that said something about creating a function inside a timeout event. Should all variables and objects be declared outside of the button click function?
I'm learning some C# and in the tutorials, they usually put most of the code on the button clicks for the sake of teaching
The reason that putting code inside a click handler would be bad is that a click handler is specifically related to the UI, and the rest of your code might not be.
A stream reader reads from a stream. Code that processes a stream should be grouped with it. Code that handles the fact that you clicked on the UI has nothing to do with reading from a stream, so it should be separated.
Generally you should group your code so that parts of your code that are logically similar are together, and that parts of your code that deal with entirely different things are separated. This will give you "high cohesion". It is related to the Single Responsibility Principle.
Should all variables and objects be declared outside of the button click function?
Absolutely not. If it makes sense to create a specific object when handling a UI event, do so.
However as I mentioned before, if you're dealing with non-UI things inside a UI click handler you're doing too many things at once. Split out your streaming code into another method, another set of methods, or into another object. This will make it easier to read your code, it will make your code have a better chance of being reusable, and it will make it easier to edit your code.
UI logic and flow is notorious for being kludgy and requiring a lot of work-arounds and special handling. It is also the area of your app that you will get the most feedback on, so it will undergo the most change. Everyone will have an opinion on how your UI should work, including non-technical users. If you guard yourself against this by separating your UI logic from the logic in the rest of your app, then those changes will be much easier to make.
You can create instances within your handlers, this is common practice as everything is taking place on the UI thread within your handlers. In addition once the method completes that variable will go out of scope and get marked for garbage collection.
It all depends on how long you need the object to live, if you wont use it outside the button event then it probably should be there so it gets garbage-collected when the event is finished, if you do need to use your objects outside then using a field in your class should be fine.
No it is not a bad idea to create instances in event handlers, but if there is any code that you may want to call multiple places in your code, it is best to that part of code to a separate method instead of trying to simulate button click events
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.