Should custom controls be used to manage form complexity? - c#

In general, I am wondering when to use custom controls vs integrating the control directly into your form.
In particular, I have a form that contains a tab page, with 6 tabs each containing a number of .net framework controls. Currently, I have in my project 6 user defined controls that I dock onto each of those tab pages.
I.e. there is no reuse of controls, I just use them to manage the complexity of a form that would otherwise contain 10 gridviews, 20 buttons, 6 date controls, etcetera. Would you consider this a good way to manage this complexity, or would other alternatives be better (in enabling the programmer to
understand what is going)?

I think this kind of division of page to custom/usercontrols may prove to be useful even without reusing the parts. This gives you:
Encapsulation - you can hide the boring plumbing and fragile internal state from higher level code, leaving you a much cleaner set of controls to work with and more business-oriented code on page level.
Separation of concerns - you can make pieces which are simple, yet logically whole.
Readiness for reuse - may never become useful but it does make you feel more powerful ;)
But be aware that this can backfire if your components are not properly named and grouped, badly designed, you use lots of dynamic loading, do not provide good API or nesting goes too deep. I have seen it happen in a legacy app and it wasn't helpful that way.
If done well, worth it. With inexperienced/sloppy team members, better don't.

What is complexity for you? If you ask me, you are making it more complex if you use usercontrols as the way you use. Usercontrols should be used to prevent code duplication. Basically what you are doing is moving your logic to your usercontrol and deviding your logic into multiple pages so you have less code on your main page. This shouldn't be your main concern if you ask me.

If you have complex logic in a view model or controller for the sections of screen, then this can be a beneficial approach. It is making your overall form more of a composite. You can develop the functionality behind the sections/controls in the view models and/or controllers separately and unit test them separately. As ImreP says, this is along the lines of separation of concerns.
However, if there's a lot of interaction between the separate controls on your form, then this might not be the right way. If you can find separate areas of behaviour/responsibility for different areas of the form, then the split may be a good idea, given your premise that there is quite a lot of UI happening.
If it's simply for the sake of having fewer basic controls in each package, and there's no chance of reuse of any of the components, then it might be muddying the waters somewhat.
A good test might be to show it to someone else on your team and see how long it takes to explain it to them. You'll get a good idea if it's intuitive or not by trying to show it to someone who hasn't come across it yet.

Related

WinForms-Preventing form conflicts

Our application has a central main form. Since we are at the start of the project a lot of buttons and controls are being added to this form. This, as expected, creates conflicts when merging our code together using VCS. It is also almost impossible to solve the conflicts since the designer part of a form is generated automatically.
I was wondering if there is a practice or workflow strategy to minimize conflicts in a form where several people work on.
Remove as much logic as you can so your form becomes simply a view. This minimizes the conflicts - but it doesn't resolve them entirely.
Your best strategy is to make sure people pull from and push to your master/trunk/branch as often as possible so the conflicts are minimal.
If your team mainly works on feature branches, then have someone dedicated (or a couple of developers working closely together) do the feature merges back to your master/trunk. The conflicts will be many, but this alleviates the need for individual developers to track merge conflicts and attempt to fix them in isolation. The developer(s) responsible for the merging back to master/trunk will know what needs to come in/be left out and can manage it as part of their process.
Again though - your best bet is to make your form literally be a dumb view that does nothing but render controls. Everything else should be handled elsewhere.
The only techniques I've seen are:
Refactor to controls so that impact is minimal
Limit your UI changes to be just the designer or developer with best ux intuition
Use the "lock" feature of the VCS system if your VCS system supports it. That will prevent others from checking it out if you're working on it.
.NET has a tool for that, it is called a UserControl :
Separate your form in multiple custom UserControls, each of which can be developped independently. Eventually your MainForm would be the assembly of a few high level UserControls, each being itself an assembly of UserControl etc...
Creating UserControl will also allow you to reuse them in other parts of your appliction, making it much more fleible and easier to maintain
You can follow MSDN tutorial about creating a UserControl.
Do not work with a single Form.

Can the Architect be right "MVVM only splits the code behind to multiple (3) files "

I am pretty new to WPF and I have an discussion this morning with my architect who is from C,C++ background.
We are trying to create a video calling application which depends on native dlls by making PInvoke. The WPF application is mainly the UI and in code behind we are making Pinvoke Calls for Video /Audio and listing the available drivers.
So If we are talking Data as from database then there is not much of the "Data" involved in our application.
The WPF application we are trying to modify is Boghe and surprisingly they too are not using MVVM.
While I am keen on implementing MVVM the architect points it as unnecessarily splitting the files in to 3 parts.
He says if we want to change any thing in the view like changing a button or any control then it can be directly done in code behind. Why then use MVVM?
Though I have theoretical answers but can't help but agreeing to his point. Is he actually right?
He says if we want to change any thing in the view like changing a button or any control then it can be directly done in code behind. Why then use MVVM?
Of course it can be done this way. The question is whether it should be done this way.
For a fairly small code base, you can probably get away with mixing up data access, core logic, and UI manipulation in code behind. In the long run however, that will not make for maintainable or testable code, and the mess is likely to get worse over time and turn into spaghetti code. Take my word for it, because a good portion of my time at work is put into reversing such old messes.
Some consequences of mixing everything up in code-behind are:
Code that fundamentally violates the "Single Responsibility Principle" (SRP).
Code that's hard to understand because it does very different things all in the same place.
Code that breaks easily. I change something here and for some arcane reason, some feature breaks over there.
Code duplication / violation of the "Don't Repeat Yourself" (DRY) principle. You often find the same logic in several places. Is this accidental, or on purpose? If I change logic here, must the same/similar logic over there be changed too?
Note that with the exception of the first point, these are not theoretical concerns, but very real, immediate problems of your typical "legacy" code base.
In my opinion, it's not entirely correct to say that MVVM introduces more code-behind classes. This is clearly a statement from someone who does not appreciate the fundamental separation of concerns that comes when you isolate the data, business logic, and UI logical layers from one another: Even with MVVM you have only one code-behind class for your views. The other two classes (yes, there will likely be two more) simply can't be considered "code-behind" because they aren't directly tied to the view / designer.
Short Answer: No!
ViewModels are not the same as Codebehind in different files.
With a proper MVVM implementation, you do not have a codebehind, or at least
a very small one.
But in the ViewModel you do not have direct access to the window, as in MVVM
the communication between ViewModel and View is done over Binding, there is
no direct reference to a View (normally).
MVVM brings in some enormous advantages over view centric approaches.
It is testable, it is far easier changeable, it is an adapter, ...
edit
And if he really is your software architect, he should know better...
at least thats what I expected from a software architect
I too agree with stakx and Mare Infinitus; MVVM provides a lot of benefits and is not just creation of multiple code behind files.
From my experience MVVM is the best way to learn and use the power of WPF, it kind of encourages and forces you to use WPF features like Binding, Commands, Styles, Converters etc. I have seen application's being developed without MVVM and they turned out to be WPF application in Winforms style having problems stakx mentioned (and more).
Apart from UnitTesting(which I think is very imp. in your application), re-usability etc. one very important benefit of using MVVM is that it can support multiple views, i.e. you can have multiple UI's for your application all of them can use same ViewModels; This may not be a requirement for you today but you may require to have a new interface few years down the line or support other platforms like Silverlight or Metro in future, MVVM will save you a lot of effort in that case.
I would suggest you to go through this post which explains real benefits of MVVM and explains other so called benefits (although I feel they are real benefits in practice) - MVVM Backlash
one purpose is that you can unittest your view logic(viewmodel) without the view.
here one nice comment from Rachel regarding viewmodel first approach:
Remember, with MVVM your ViewModels are your application. The View is
just a pretty interface that allows users to interact with your
ViewModels.
If you have only two people in the project, and everyone's all-in-one person, he's right.
But if you do not want designers messing up the controller (or ViewModel), or programmer that changes view to something, you know, as programmers do design.
In addition, You have the clue where to do changes immediately, without searching enormous text files.
Also, the separation by MVVM or MVC is one of basic principles of programming, it's Data-Logic-View separation, and if architect says you not to do it, may be it's time to ask another architect :)

How do you implement sophisticated UI logic?

I'm looking for best practices for sophisticated UI logic implementation. I'm working on a Windows Forms application, but I believe there should be generic patterns for solving this problem on any platform.
I have a number of controls on my form, there are lists, buttons, tables and a tree view. So, the idea is that depending on "context" some of the controls are enabled, while others are disabled. Some of them can provide some features for the moment and others don't.
Currently it's implemented "as is". I handle events, check for changes (new tree node selected, couple of nodes selected, etc.) and then decide whether some of the controls need to be disabled or enabled. I don't really like this approach because the Form code looks to complicated. And if I need to add more logic, it becomes even more complicated. I'm really concerned, since we're quite agile and new features or lots of changes are the daily norm.
I'm thining of separating all this logic into parts (Features), where each feature is an object that know how to check its state, and depending on this state, enable or disable the related controls.
Don't really want to invent anything new and trying to find any good ideas that are widely used. Please, don't recommend single UpdateUI() method approach, I believe that won't change anything in the long term.
Thanks.
This blog series may be what you are looking for:
http://codebetter.com/jeremymiller/2007/07/26/the-build-your-own-cab-series-table-of-contents/
(may look like a lot of material, but start just with the "Humble Dialog box", based on Michael Feathers great article). This is all about "how to separate your logic from your UI code", which may solve most of your problems.
User interface data binding and encapsulating your business logic into business objects is the way to go. CSLA.NET framework by Rocky Lhotka has a lot of great features built-in as well as a number of sample applications. I've used it in a medium-size WPF project and a huge WinForms/CAB application and really enjoyed it.

Is it 'wrong' to make User Controls if it is not for reusability?

I can't decide if it is good or bad to make many user controls. I am only doing it cause I find it easier to work on a control where there are not a lot of components. If something needs to be fixed it is also easier. Kind of like how you split your program up in a lot of classes.
However multiple controls adds a bit more complexity when it comes to passing data around. I guess my question is more if it is normal to create a 'god' class when it comes to GUI programming in winforms.
Almost every video tutorials I see, they only work on one form! While I can use like 5 controls before I have a form.
Reasons to create User Controls in WinForms:
Reuse of functionality.
Encapsulation and data hiding.
Readability and maintainability.
Single responsibility principle.
Design-time editor integration for assignable properties.
Ability to refactor/enhance/reuse in the future.
Have you heard about encapsulation and components? It is just your case.
Well from a Web Developers perspective -- no, I don't believe so. In fact I believe in the NerdDinner book for ASP.NET MVC there's a section where the author(s) creates a partial (similar to usercontrol) for the sake of readability purposes. And these are the top guys at MS who wrote this book.

organizing gui code in c#

what are the best ways to manage code in a single-form app that has many different components? for example, think of a financial app that has a product picker for browsing/choosing a product to view; a handful of real-time tickers for prices, interest rates, or whatever; a scrolling news feed; various charts; a grid displaying locally calculated values; etc.
would you create a custom control for each distinct component, even if they're not going to be used outside of this app? or could you do it with classes that implement the logic for each component and somehow update that actual control in the gui? two components may need to interact with each other, e.g. you click a cell in a grid, and it brings up some chart (would the main form handle sending the message?)
I have a habit of letting form code get bloated as features are added and I really want to get familiar with a better way. I'm working with c# (not using WPF) but I guess basic design principles aren't necessarily language-specific.
You can try the MVP pattern.
See - Gui Architectures by Martin Fowler
It somewhat depends on how large the application scale is, and also the lifetime of the application.
In nearly any reasonably sized application, I'd recommend separating individual sections into separate UserComponents. That being said, there are many ways to move beyond that, including using plugins/DI, etc.
I'd recommend reading (or at least skimming) the Composite Client Application Guidance for ideas. The message passing questions as well as the questions on different approaches to tie together individual components are discussed in detail.
There are many gems that would be relevant in the Composite Client Appilcation Guidance, even though you're not using WPF or Silverlight. Many of the sections in the guidance are not technology specific - they relate more to how to bring together multiple pieces, promote reusability and flexibility in the design, etc. These apply no matter what technology you are using.
I tend to do everything as a custom control and them use panels for my placement. I then create a new instance of the control and add it to the panel.
This allows for me to do custom constructors, which I have been finding more useful as I am trying to use a DI/IOC framework on my current project.

Categories