A lot of times, I find myself doing UI control manipulation in the code behind and wanted to find a clean way of doing this.
Use Case:
A drop down has CSS1 style, editable in Edit mode but
has CSS2 style, view only in View mode
I can achieve this by simply have a set of switch case statements. I can use polymorphism and create a EditMode and ViewMode class but that requires me to have a reference to the UI control to be passed to these classes. This tightly couples the UI and the logic layer which I want to avoid.
Any ideas?
EDIT:
Can anyone give an example of externalizing the UI logic from the code behind?
Passing a control does not necessarily tightly couple, but I can understand the reasoning and would agree with it, as a general rule.
One option is to create the class as a UI class. This does not mean it has to be embedded in the ASP.NET web application, but rather that the library is set up as a web UI library. I do this by naming:
company.application.UI.{libraryName}
Your naming may be different.
In architecture, there is nothing wrong with having UI libraries that have polymorphic helper classes. I would not move these classes down to the business layer.
Take a look at Dynamic Data Web Application. There you can find one way to cleanly separate view controls from edit controls.
Related
I have a form with 3 tab controls on it, and each tab control has a dozen or so text fields. Right now I have all of my methods for modifying the text fields within Form1.cs, which is working, but is a very long class. I am curious if it is propper method to keep methods that call Form controls within that forms class, or if you should divide them out into other classes? I read this thread and I may be confused, but it sounds like the chosen answer is saying you should not try to access form controls from other classes?
How to access form methods and controls from a class in C#?
The best method for encapsulation in this scenario is to create user controls that contain the text fields for each tab. Then, each tab just has a user control on it, and all the logic specific to those fields is encapsulated in its own control.
if you can leave the code that accesses UI data inside the Form, but the code that operates/executes computation over that data into another class. In this way you will be able to create a single class, or a set of classes, which can be used for (say) UnitTesting.
It's easily done, you just pass a reference to the form to the other class, but then they become tightly coupled and therefore fragile.
A better option would be to define an interface and have the form implement it, that can get messy though.
Other options would be move the controls on your tab to a user control or even just another form and then host them in your main form's tabs. Then you could isolate the data and operations of each tab. Again defining and implementing an interface or two will help you decouple.
Think of it this way, you separated out the UI in to tabs, there is some underlying logic behind that from a UI point of view so it follows, there should be some logic in terms of separating the functions the controls on the tabs perform. I have seen exceptions to that, but it was usually because the separation in the tabs had no logic at all.
There are different ways to organize applications. It is usually a thing to separate the GUI (the forms) from the other application logic. Do only display logic in the forms. Create data classes (also called models) for you data. You might want to have classes like Customer, Order, Address and so on. These classes contain the "business logic", e.g. the Order class knows how to calculate the taxes, not the order form.
You can save you a lot of effort by using data binding to bind your business objects to the forms. See my SO answer for the use of data binding.
You can go even further by separating the logic into three parts by using the MVC pattern. I am not going to explain it in detail here. Just this, MVC stands for Model View Controller. Model is the business class, View is the form and Controller is a class that manages the model and the form, loads and stores the model etc.
How can I expand the implementation of a wpf using my own custom classes? In particular, I want to create new C# classes on a wpf beyond the ones that derive from App.xaml and MainWindow.xaml. Should I add them directly on the project? If so, can I use references of the MainWindow elements inside them in order to tweak their functinality and add new tasks? Should they derive from the MainWindow class?
What is generally the most reasonable way to expand the implementation of a wpf to other new classes?
That is a rather broad question and where to place classes and from what classes to inherit are quite different problems. Both are ultimately a question of architecture though and what the right architecture for your application is cannot be answered here. It depends on what your application is supposed to do and how it should be done, all that should be planned out before doing anything with classes. You might want to read some smart book on topics such as software engineering and software architecture.
Ultimately you should get a good book on WPF, read it, and type all the examples into your editor. Simply trying to dive into an API with absolutely no example and no concept of how the architecture works is not going to get you anywhere very fast.
To answer your specific questions, though:
Should they derive from the MainWindow class?
No. To write the GUI for a WPF application, you rarely will have to use inheritance that isn't already written for you when Visual Studio generates a new app, a new window, or new user control.
It might make sense to use inheritance in your code somewhere, but rarely in the GUI code itself, and certainly not on the window or app level. The only manual use of inheritance will be for implementing custom WPF controls (the least frequent and most painful option for extending your GUI).
How can I expand the implementation of a wpf using my own custom classes?
It isn't clear what you're trying to do, so I'll try to cover all the cases.
UI
If you want a new application, usually you wouldn't derive from a specific application class at all, you'd just create a new WPF project (a whole program). Visual Studio will then create new classes for you that inherit from Application and Window.
If you want a new window, the same thing is true. You'd just tell Visual Studio to create a new window, and your classes would automatically be created for you, and they would inherit from Window.
If you want to add existing controls to a window, don't derive from anything. Go to the UI designer, and drag+drop controls from the Toolbox onto the page. Or edit the XAML for that window directly.
If you want to customize what happens when a user clicks on or works with a control, write event handlers for those controls. Or when you're comfortable about this, read up on data binding and the MVVM design pattern, since it will help you write cleaner programs.
If you're trying to customize the way your app or controls look, you'd usually use data templates, styles, user controls, and custom controls, in that order of frequency and difficulty. Except for custom controls, none of those involve manually written inheritance. When you add a User Control in WPF, Visual Studio will write a class that inherits from something, but you don't have to worry about that fact.
Non-UI
If you're trying to write the guts of your application, you probably should avoid writing any UI code.
It is a good practice to separate your UI from your main application guts. That way if a brand new technology comes out, you can strip off the UI, and throw the guts into a new program. Or if you decide to put those guts into a web page, that will also be possible.
You can reference this new code from the code-behind in the UI, or using the MVVM design pattern (which you should eventually read up on), but you should avoid mixing your UI specific code and your non-UI code as much as you can.
This means you won't inherit from any UI classes in order to implement the guts of your app.
I have seen couple of discussion on where to write UI validation in MVP.
There is quiet confusion over this as suggestion on keeping view and presenter. But displaying message box in presenter does not looks very good similarly putting logic in view restrict us from unit testing.
One more aspect is Sharing validation across the application. My thinking is to keep the UI validation in UI model by passing presenter. Even we could reuse this and also it reduces the size and complexity of the presenter. Handling in UI model looks more object oriented.
Is it right approach? Can you guide me on right direction?
The pattern is typically that all functionality should go in the presenter, that way it's reusable and testable. That doesn't mean you can't create some sort of validation display control to display them nicely.
Have a look at the way Silverlight RIA services does it.
I am developing a large-ish application in WPF/WCF/NHibernate/etc. and have implemented the MVP pattern (although this question is still relevant to MVC) as the core architecture.
It feels quite natural to extend and add functionality as well as to come back and make changes on certain bits and pieces, as far as the core architecture is concerned (controllers, views, etc).
But at times the code-behind-ness of custom user controls that I create feels as if it "breaks" the MVC/MVP paradigm implemented, in that code concerns leak in the design and design concerns leak in the code. Let me clarify again, this is only for user controls. It is my personal opinion that this code-behind model (for both ASP.NET and WPF) is a 'Bad Thing', but no matter what my opinion, I'm stuck with it.
What are your recommendations for best practices in such a scenario? How do you handle such concerns? Do you for instance work around the code-behind-ness of custom controls and if so how??
Since you are using WPF, you should really look into the MVVM (Model-View-ViewModel) pattern. It is a form of the Presentation Model (PM) pattern discussed by Martin Fowler. WPF is very binding-oriented, and provides a very powerful and rich data binding framework for XAML. Using MVVM, you can completely and entirely decouple your ViewModels from your Views, allowing truly POCO UI development that offers the ultimate in separation of concerns and unit testability.
With MVVM, you will be able to modularize and decouple all of your views, including Windows, UserControls, etc., from the code that drives them. You should have no logic in Code Behind other than what is automatically generated for you. Some things are a little tricky at first, but the following links should get you started. The key things to learn are the MVVM pattern itself, Data Binding, Routed Events and Commands, and Attached Behaviors:
MVVM
Data Binding
Attached Behaviors
Attached Commands (VERY USEFUL!)
Routed Commands
Routed Events
WPF + MVVM has a bit of a learning curve up front, but once you get over the initial hurdle, you will never, ever want to look back. The composability, lose coupling, data binding, and raw power of WPF and MVVM are astonishing. You'll have more freedom with your UI than you ever had before, and you will rarely, if ever, have to actually bother with code behind.
I happen to like code-behinds (yet another personal opinion), but they work only as long as they do nothing but facilitate interactions between control events and the rest of the application. I'll admit that I've seen a lot of counter-examples, though. I even wrote a few of them....
Really, all the code-behind should do is "oh, someone clicked this button; there's probably something that wants to know about that." PRISM (from MS patterns and practices) provides a lot of architectural infrastructure for WPF and Silverlight; that includes a publish/subscribe interface that allows the controls and the code-behinds to simply publish an event while not even being aware of possible subscribers, or what the subscribers might do with the event. PRISM also adds commands for Silverlight.
A common variant of MVC for WPF and Silverlight is MVVM (Model, View, ViewModel). The ViewModel makes data available to the user controls in some form that is most useful (such as ObservableCollections, to facilitate two-way binding).
Custom Controls are there to display stuff. In that regard they are no different than a button or a drop down combo box. The trick is that don't let them handle stuff directly. They need to send stuff through the View Interface and the Presenter need to likewise interact with them through the view interface.
Think of it this way. If you ignored MVP the custom control would interact with the model in specific ways. what you doing with MVP is taking those way and defining them with the View Interface. Yes you are adding an extra call layer but the advantage is that you thoroughly document how it interacting with the rest of the system. Plus you get the advantage of being able to rip it out and replace with something entirely different. Because all the new thing needs to do is the implement it's portion of the view interface.
If you have a specific example I can illustrate better.
I am currently writing a little game with standard UI controls.
It is working great so far but what I don't like is that I am managing the controls in the codebehind file. (C#)
As I am trying to decouple all elements, I would like to have a separate engine / controller which handles all the data management and the logic for my user interface.
Is there a possibility to register the controls with the engine so that I don't need to pass them down with every method I call?
Currently I am forced to pass the controls every time I call the function..
Thanks in advance!
Will be good if you can elaborate more on your current implementation. From what I can understand, instead of trying to figure out how to 'register the controls with the engine', why not try to see if it's a design issue.
Perhaps there's a better way to structure your app/classes/components so that you can decouple logically for better reusability and maintainability?