I have a class which adds some functionality to a windows form textbox. For example, it handles textbox key down event and based on some sort of logic, if 'Enter' was pressed then an special grid is shown to let the user select one entity from a large number of entities. So I call this class 'Textbox Extender' and the textbox 'Extended'.
Now, I want to make the user informed that whether a textbox is extended by changing it's back color, pretty easy to add this functionality to the class BUT:
I am very suspecious it is against Single Responsibility Principle. Any idea is highly appreciated.
Its not against ssr. Your class responsibility is to extend textbox functionailty.
Single Responsibility Principle say that your class should only fullfill one purpose, what is the purpose of your class? I would say it is to show an extended TextBox(and get its data, which you can't do somewhere else), if your UI changes do inform your User that they now have an extended textbox everything is ok with that, no violation of SRP. Anyway capsuling UI from the UI object seems like overengineering.
Related
How can I check if any control (check box/radio button) of the currently active form has been selected/toggled?
My goal is to create an option called Save changes automatically which would enable saving the current state of check boxes and radio buttons, so I need to know when any control is selected/toggled (to execute the save settings method). I don't want to create a separate event handler for every control, I'm looking for a generic solution if it is possible.
This is not a job for the user interface.
Use databinding to change a Model in code-behind and let the model trigger/escalate changes.
To help you on your way a little:
Your checkboxes and other controls are not where your data is. They should only show the data.
Create an object (the Model) with boolean properties for the checkboxes and int/enum properties for the radioboxes. Set up the databindings from the controls to the properties.
Then you can implement the necessary logic in the Setters of the properties.
As Henk proposed, you could use a Separation of Concerns pattern such as MVC to separate UI and domain logic. As the user makes changes to some UI widget, you update the value in the model, for example by setting a property. The property setters could then update a IsDirty (or HasChanges, ...) field. This property would be read by the UI which would, depending on the value of IsDirty, decide what needs to be done. (Display a MessageBox("Do you want to save your changes") or something else)
I do think that Henk was thinking web while you tagged the question with WinForms. Chances are you are not using a pattern to separate UI and domain logic. (and that UI and domain code are already so intertwined that your current deadline does not allow you to introduce a model right now)
You could achieve the same thing by placing the IsDirty field on your Form and having the Changed EventHandlers set that IsDirty value. By subclassing the Form (ie put the IsDirty on your 'FormBase') and your controls (for example by introducing a watermark), you could have this behavior out of the box for all your forms.
I want to refactor some code.
Basically the code I want to refactor is a Form (using System.Windows.Forms;)
The way it is setup now, depending on which radio button you selected it shows a different layout for the window: different labels, buttons, etc. Not always a big difference, but different. This is a lot of conditional statement junk all over the place. I wanted instead to refactor it with the State pattern. There are three main states.
I'm not sure the best way to do this. Right now the IState interface has a DoAction() method which does some action particular to the unique State, and a DrawForm() method which re-draws the form based on the current State... However, to do the DrawForm(), the State classes need to be able to access the Form's member variables. That's what threw me for a loop. I didn't really want to expose them.
Is there a better way to do this?
You could make your state classes nested in your form. They will then be able to acces fields of form without having to expose them.
If your primary concern is keeping form stuff encapsulated, and you want to keep the state machine outside, I had a similar question a while back, you could check out the answer here - basically it entails creating a private inner 'action' class which DOES have access to form methods, then passing this to the state machine so that it can use the action class to invoke form methods indirectly.
I don't know if this helps, but why not have something like a strategy pattern for drawing the form?
So something along the lines of
interface IDrawStrategy
{
void Draw(FormType form);
}
And then when you pick which state the form is in, you can assign the form's draw strategy. Yes, you will still need to give the draw method access to the Forms variables to allow it to position them, but it at least allows you to make it easier to add different looks based on the states.
In wanting to extract the "state" of the Form, you are describing a pattern better known as a "Presentation Model". You will find some good information and tips on how you generally want the Form and State to interact by reading this article by Martin Fowler. In your case, your Form is the "View" and your State is the Presentation Model. As always, Fowler does a great job answering this question and more.
I have a a user control which contains several other user controls. I am using MVVM. Each user control has a corresponding VM. How do these user controls send information to each other? I want to avoid writing any code in the xaml code behind. Particularly I am interested in how the controls (inside the main user control) will talk to each other and how will they talk to the container user control.
EDIT:
I know that using events-delegates will help me solve this issue. But, I want to avoid writing any code in xaml code-behind.
Typically, it's best to try to reduce the amount of communication between parts, as each time two user controls "talk" to each other, you're introducing a dependency between them.
That being said, there are a couple of things to consider:
UserControls can always "talk" to their containing control via exposing properties and using DataBinding. This is very nice, since it preserves the MVVM style in all aspects.
The containing control can use properties to "link" two properties on two user controls together, again, preserving clean boundaries
If you do need to have more explicit communication, there are two main approachs.
Implement a service common to both elements, and use Dependency Injection to provide the implementation at runtime. This lets the controls talk to the service, which can in turn, keep the controls synchronized, but also keeps the dependency to a minimum.
Use some form of messaging to pass messages between controls. Many MVVM frameworks take this approach, as it decouples sending the message from receiving the message, again, keeping the dependencies to a minimum.
Your conceptual problem is here:
Each user control has a corresponding VM.
Having a separate ViewModel for every view pretty much defeats the concept of a ViewModel. ViewModels should not be one-to-one with views, otherwise they are nothing but glorified code-behind.
A ViewModel captures the concept of "current user interface state" -- such as what page you are on and whether or not you are editing -- as opposed to "current data values'.
To really reap the benefits of M-V-VM, determine the number of ViewModel classes used based on distinct items that need state. For example, if you have a list of items each of which can be displayed in 3 states, you need one VM per item. Contrarily, if you have three views all of which display data in 3 different ways depending on a common setting, the common setting should be captured in a single VM.
Once you have strucutred your ViewModels to reflect the requirements of the task at hand you generally find there is no need nor desire to communicate state between views. If there is such a need, the best thing to do is to re-evaluate your ViewModel design to see if a shared ViewModel could benefit from a small amount of additional state information.
There will be times when the complexity of the application dictates the use of several ViewModels for the same model object. In this case the ViewModels can keep references to a common state object.
There are many differenct mechanisms for this, but you should first find out in what layer of your architecture this communication belongs.
One of the purposes of the MVVM framework is that different views can be made over the same viewmodel. Would those usercontrols talk to each other only in the view you are currently implementing, or would they have to talk to each other in other possible views? In the latter case, you want to implement it below the view level, either in the viewmodel or the model itself.
An example of the first case may be if your application is running on a very small display surface. Maybe your user controls have to compete for visual space. If the user clicks one usercontrol to maximize, the others must minimize. This would have nothing to do with the viewmodel, it's just an adaption to the technology.
Or maybe you have different viewmodels with different usercontrols, where things can happen without changing the model. An example of this could be navigation. You have a list of something, and a details pane with fields and command buttons that are connected to the selected item in the list. You may want to unit test the logic of which buttons are enabled for which items. The model isn't concerned with which item you're looking at, only when button commands are pressed, or fields are changed.
The need for this communication may even be in the model itself. Maybe you have denormalized data that are updated because other data are changed. Then the various viewmodels that are in action must change because of ripples of changes in the model.
So, to sum up: "It depends...."
I think the best solution would be using Publisher/Subscriber pattern. Each control registers some events and attaches delegetes to events exposed by other controls.
In order to expose events and attach to them you would need to use some kind of Mediator/EventBroker service. I found a good example here
The best way to do this in my opinion is via Commanding (Routed Commands / RelayCommand, etc).
I want to avoid writing any code in the xaml code behind.
While this is a laudable goal, you have to apply a bit of practicality to this, it shouldn't be applied 100% as a "thou shalt not" type of rule.
You can communicate between elements on the UI by using element binding, so assuming a user control you created exposes a property, the other user controls could bind to it. You can configure the binding, use dependency properties instead of basic properties / implement INotifyPropertyChanged but it is in theory possible, but does require some forethought to enable to communication this way.
You will probably find it far easier using a combination of events, code and properties than try a pure declarative way, but in theory possible.
You can share some View Model objects between controls as well as Commands...
For example, you have some main control, which contains two other controls. And you have some filtering functionality in the main control, but you want to allow user to set some part of the filter in the first sub-control (like "Full filter") and some part of the filter in another (like "Quick filter"). Also you want to be able to start filtering from any of sub-controls. Then you could use code like this:
public class MainControlViewModel : ObservableObject
{
public FirstControlViewModel firstControlViewModel;
public SecondControlViewModel firstControlViewModel;
public ICommand FilterCommand;
public FilterSettings FilterSettings;
public MainControlViewModel()
{
//...
this.firstControlViewModel = new FirstControlViewModel(this.FilterSettings, this.FilterCommand);
this.secondControlViewModel = new SecondControlViewModel(this.FilterSettings, this.FilterCommand);
}
}
public class FirstControlViewModel : ObservableObject
{
//...
}
public class SecondControlViewModel : ObservableObject
{
//...
}
In the main control XAML you will bind sub-controls DataContext to the appropriate View Models. Whenever a sub-control changes filter setting or executes a command other sub-control will be notified.
As others have said you have a couple of options.
Exposing DepedencyProperties on your user controls and binding to those properties provides a pure XAML solution in most cases but can introduce some UI dependencies in order for the bindings to see each other
The other option is a decoupled messaging pattern to send messages between ViewModels. I would have your user controls bind to properties on thier own VM's and then on the property change inside that VM it can "publish" a message that notifies other "subscribers" that something has happened and they can react to that message however they want to.
I have a blog post on this very topic if it helps: http://www.bradcunningham.net/2009/11/decoupled-viewmodel-messaging-part-1.html
If you're using strict MVVM, then the user-control is a View and should only "talk", or rather, bind, to its ViewModel. Since your ViewModels most likely already implement INotifyPropertyChanged, as long as they have a reference to each other, they can use the PropertyChanged events to be notified when properties change, or they can call methods (better if it's through an interface) to communicate with each other.
When looking into MVC frameworks for flex, as3, silverlight, and wpf... a common concept of ICommand / commanding keeps appearing... Can anyone explain the advantage of using ICommand / Execute() ?
Where I dont see the value added is - Why can't the controller map the input (ie: a click event) to the correct method inside of the model? I'm assuming it is because commanding buys you something - like removing business logic from the controller / the would-be event handler in the controller.
Thx.
Here's a couple of cases that demonstrate the value commands add:
Suppose you have a simple form with a text box and Submit button. You want a button to become enabled only if some text is entered into the text box. With commands all you have to do is to implement CanExecute method (to return true or false depending on the value in a text field) A framework will automagically disable/enable button accordingly. With code-behind (or controller) approach you'd have to write a code do enable/disable button manually.
Suppose later you decided you don't like the button control you used, and decide to switch to a new control (being that a button, or something more exotic) from a different library. All you have to do is make a change in XAML. Any control that supports Command binding will know what to do. In code-behind approach you'd have also modify your button click handler (since new control will probably require different event handler signature)
Suppose later you decide to add a checkbox to your text field that would visually indicate to user whether the content of that field is acceptable. All you have to do is to bind this new checkbox to your command's CanExecute, and now you have two controls already that would automatically change their visual appearance depending on whether form is submittable. With code-behind approach (or controller) addition of a new control would require adding more code.
Suppose you want to test your action. Since commands don't depend on any visual elements, and don't need them, you can easily write a unit test that will not require user clicking any buttons, or entering any text. With controller approach you'd have emulate controller's events, and mock the view.
Summarizing:
Commands provide a well-defined interface between the business logic and the presentation. Business logic implementor doesn't care about how visually certain action (e.g. command) will be implemented. He simply provides the action implementation and an ability for a presentation to query the state of the action. He doesn't care what particular UI element (or elements) will trigger that action, how exactly (in)ability to execute that action would reflect in UI, and what changes UI might go through in the future. At the same time presentation designer doesn't need to know anything about event handlers, controllers, etc. He has a Command and he plugs it in to any UI element (or elements) he chooses without the need to go to C# code at all.
What controller are you talking about?
The Commanding concept in Silverlight and WPF is used to tie together (through binding mostly) the UI to business logic (be it a controller/viewmodel/model/etc).
That is the point, to move the functionality of the command outside of the UI.
Example. Saving a widget in your application is probably always done the same way. Sure, you might let the user change the name, or this or that, but the overall behavior is always going to be the same. Now, in your application you might actually initiate saving a widget through a lot of different UI avenues such as Page 1 has a button on the right hand side that saves the widget on that page, Page 2 has a menu item on the top that saves the widget on that page. The UI is different but the behavior remains the same.
You can accomplish the same goal by using Event Handling (such as grabbing the click event on a button), but now you're back into the context of dealing with UI specific issues. Commanding, arguably, has a cleaner separation.
The simple answer is that commands are bindable whereas events are not. So if you want to respond to a button click event you can either:
Attach an event handler in the code behind.
Create a click command and bind it to the ViewModel's command.
Since one of the goals of MVVM (which is the more common pattern for Silverlight and WPF over MVC) is to seperate code and UI. So if you take the first approach you end up with code in the View. If you take the second approach you can seperate the code from your view using commands and bindings.
I could use some advice/help on a piece of software I've developed.
The application is a wizard style app where users fill out fields on each form before choosing to go to the next form or back to the previous. Fairly simple.
Right now the menu calls frmWiz1(InitialData) and when frmWiz1 returns with DialogResult.OK the menu will call frmWiz2(frmWiz1.Data) (not exactly, it stores all of the Data from each form, and passes those references in to the next form). Each data object inherts from an IPrintable interface that defines methods for printing itself, so at the last page in the wizard (print preview/sign), it adds each Data object to a custom PrintDocument object that just iterates through the data objects, calling their print functions and manages pagination etc.
Initially I thought this was a good idea but now I'm thinking that:
- The menu form is handling too much flow logic.
- The Data objects (which handle all of the business logic that applies to their particular set of data) should be decoupled from print logic (cause as they are now, they're in the printing namespace - maybe just a relocation will set my mind at ease).
I don't know. I'm decent with the language, but I'm still a rookie at design.
Screw "frm" prefixes!
With respect to the overall flow of the application, I would recommend using Application Controller or something of the kind in order to centralize the logic.
As far as the UI goes, each Wizard stage should be a separate User Control (with no "Cancel", "Finish", "Next" or whatever buttons) wich is placed on the root form with the aforementioned buttons.
No object should be responsible for printing itself - use IPrinterService for doing that.
Just a few general thoughs:
This is a great Wizard control. We use it here at work, and I must say this guy did a real good job with it. Not sure if it can be useful to you, but check it out
Figure out exactly what you need to know about an object in order to print it. Try to come up with methods and/or events that you would need an object to have in order to be "printable". Put those into an interface, and have your business objects implement that interface. Then, have your printing helper class deal strictly with interfaces.