I'm fairly new to ASP.NET and programming in general, and one of the problems I'm currently struggling to grasp is reducing repetitive code.
My goal is to have a master page that contains a grid view, then numerous pages can contain the grid. However, I want to be able to share code between my grids but at the same time be able to adapt unique code to each and everyone of them as some will have different attributes and data.
I've looked into separation of concerns, and other various posts/blogs but haven't found a definitive answer to how I can actually achieve what I want.
I've already tried using master pages and it worked quite well until my application continued to expand, plus I'd prefer to only use my master pages for presentation.
Could anyone provide a simple example of how I can achieve this?
Happy to provide additional information!
After spending the day doing research and testing numerous possibilities I've pretty much answered my own question.
I've setup a master page that contains the grid, the content page then retrieves the grid using accessors. This grid is then set to a property in the base class which makes it accessible where I need it to be.
edit
Event handlers were created to handle the grid events in the content pages, then those methods were overridden to allow the calls to bubble up to the base class thus allowing me to assign unique, page specific and common code where I needed it to be.
Related
I try to avoid code behind in views, within my WPF MVVM project.
However I have some things that are very specific to the view. For example when a control gets focus I want the full text to be highlighted (even if a user clicks into the text box).
Here I have a choice to handle this in the view model (which would then need to know about the view, which I want to avoid).
I also have some other code like that does things to the UI when the user presses up down left or right on the keyboard (and they only make changes to the view, not the model or viewmodel) and again I'm thinking the best place for these is in the code behind of the view.
So I'm asking if the code only affects the view (e.g. things like cursor movement, selecting all text in a text box etc..., and not the model or view model, is it okay to put it in code behind, rather than elsewhere.
Wondering what is best practise here, or if anyone else has a better suggestion where to put this code.
So I'm asking if the code only affects the view (e.g. things like
cursor movement, selecting all text in a text box etc..., and not the
model or view model, is it okay to put it in code behind, rather than
elsewhere.
Not only it is OK, but it is strongly encouraged.
MVVM is not here for you to write thousands of ugly lines of code in ViewModels, it's here to make the code testable and to introduce a separation of concerns.
If it's purely related to the view (your "focus" example is a perfect example), then just write it in the code behind.
If the behavior is UI related only, then you should not put it in the ViewModel. The highlighting example you gave is a good example of such a case. Having said that, I would suggest you avoid repeating your code by (for example) creating a custom control that highlights the text when it has the focus. This way, you can reuse the control in as many views as you can, your views stay free of codebehind, and if you optimize your control, the optimizations happen across the board.
EDIT:
In light of Ravi's answer, Behaviors are also a way to introduce UI related logic while leaving the View free of codebehind. However, if you are finding yourself repeatedly declaring the same controls with the same behaviors, in my opinion it is better to create a control that incorporates the behavior.
That being said, if said UI logic is going to appear only once in one view, you may consider putting it in codebehind. Although it is quite rare to know in advance that you are not going to need that logic elsewhere.
EDIT:
I think #ken2k 's use of strong encouragement refers to not putting it in the ViewModel, which I also advocate. UI logic should be implemented in the View, as he says. Now, there are a few ways of doing that. One of these is coding it directly in your codebehind, which can lead to repetitious code and maintenance issues. Also, if you employ unit testing, it could put you in a difficult spot. The second is coding such logic into behaviors, which is a good way to encapsulate UI code. You can then unit test the behavior to make sure it works OK. However, you can find (as I did, in many projects) that you have started to pepper every TextBox in your XAML's with behavior tags. If that starts to happen, I would (and have) create a 'HighlightedTextBox' control and use that in my XAML. In summary, my suggestion does not contradict ken2k's, but is a pointer in the direction of resolving some issues you may have when placing logic for your View.
Using Custom controls as #Boluc Papuccuoglu suggested, is good option but before using that i want you to take look here Behaviors in WPF introduction
It is strongly recommended to have all your view stuff logic at one place. Instead of polluting ViewModel you should always keep View stuffs in XAML and code behind.
ViewModel responsibility is to contain only data part which can be unit tested. With UI stuff in ViewModel, you will make it hard to be unit tested.
As per link here at MSDN, definition of code behind:
Code-behind is a term used to describe the code that is joined with
markup-defined objects, when a XAML page is markup-compiled.
As you can see, code behind is partial class of your view. One half is declared via x:Class attribute at root element and other half in form of code behind. So, as per me all UI stuff should be at one place and you should not think twice before placing the view stuff in code behind. (that's what it is meant for). MVVM never meant design without any code behind.
Also ViewModel responsibility is to just provide data to your view via data binding. It should never be aware of UI stuff.
Read more about it here - Code behind and XAML in WPF.
How much of your code do you want to unit test? If your view can trigger a command when a control gets focus and your view model can programatically fire an event to highlight the text in that control then you have everything you need to unit test that behaviour with mocked objects. And even if you don't want to unit test (or can't because the bean-counters at your company won't give you the time/budget to do so) then placing that functionality in attached behaviours means they can be used elsewhere. I'm not quite the hard-core MVVM purist as some others on this site but I can honestly say that even in the largest enterprise applications I've worked on I've never once seen a case where WPF code-behind was absolutely required.
The problem seems rather simple... I'm sure thousands of people have already figured this out, so maybe I'm overthinking it. How can I hide or show a link in my navigation bar based on the user's permission level? I am using custom roles (not MVCs) and storing that information in a database. The effect I want is pretty simple
_Layout.cshtml
...
#if(user.IsAdmin)
show link
...
There are several solutions to this I've found on the web and here on SO, but most seem to violate the MVC constructs.
Most of the solutions I found involved probing for data from within the view, which I'm pretty sure is bad practice. Other solutions involve utilizing the session variables from within the view to decide what is shown and what isn't. Isn't this also against best practices as views should not be able to decide on content?
The only "pure MVC" way I can think of doing this is to incorporate the value of IsAdmin into each of my view models, which seems like more hassle than it's worth. I suppose it's also possible to create a javacript solution where I use AJAX to figure out the admin status, then have it inject an html element into my navigation bar.
What is the proper way to handle this? Am I simply misunderstanding the best practices?
Maybe use a partial view within the layout? Something like this:
#Html.Partial(actionName: "NavigationLinks", controllerName: "Navigation")
That way, you can preserve the MVC conventions: the view can be stand-alone, and the navigation controller injects the model (whether from session data, or wherever).
So I've just started developing C# WinForm applications and each project I've been working on seems to be larger and requires more user functionality. If I add all of the functionality to one form, obviously it can get out of control very quickly. My last project I would divide up the functionality into individual Forms, and whenever someone say wanted to perform "Feature1" I would instantiate Feature1 Form and show it as a dialog with the main Form as it's owner (so they couldn't click off it).
I'm just curious of what other methods are out there for keeping code organized within Forms. If you are forced to have tons of features/functionality on a single form is there a good way to keep items organized? I simply hate having a code file with hundreds/thousands of lines long.
The answer may simply be in the design, try to design the UI up front so you can utilize multiple forms?
Another example I faced. I created a Tab Control and had about 5 tabs. Those 5 tabs had tons of features and were all stored in the same CS file. What other options did I have? Create a new custom TabControl class with my specific functionality for that tab in it?
I don't mind reading, so if there are decent articles out there feel free to link them!
The go-to method is a Controller/Presenter. The idea is that the window should only be responsible for actually handling the UI events of its controls, and it should do so by calling methods on a Controller which do the real work for the window. The window can either have the handlers necessary or it may link the UI events directly to Controller methods; the former is usually the easier method, but it can be tempting to sneak in a line of code here or there that really should be in the Controller method. By doing this, you sever the layout and presentation logic in the Form class with the business logic in the Controller.
Mark Hall's suggestion of User Controls is also a good one. By creating UserControl classes for tabs or for common UI control combinations, you sever the logic responsible for laying out that part of the UI from the main form's code, and the control then just "drops in" and the window works with it in a much simpler way. This is a must for implementing custom but reusable controls; the fundamental tenet of DRY is that if you have two lines of code in two different places doing the same job to two different but interchangeable things, those lines of code should be merged into one place.
I have used UserControls in my projects to group functionality into separate objects that can then be added to your Form.
I tend to split my logic code from the UI as recommended. If you do this, you need to be somewhat cautious with how calls are made across the application to avoid Cross Thread Exceptions. I was taught to create delegates and events to update the UI from the logic class, but MSDN of course also has a lot of information on making thread safe calls.
I know this is a late answer, but if anyone still reads this question, another way to reduce the number of lines of code in your form is to use Data Bindings. If you are using properties, Data Bindings make it so that you don't have to constantly write handlers just to do something like PropertyName = textBox.Text;. Data Bindings work with both datasets and objects.
I'm writing a flashcard program and am running into an issue I always seem to face when writing this sort of Forms program.
I'll describe the program then the issue.
In this program, one main form controls almost all of the action. Depending on the user's input and form events, different buttons/controls may become enabled or disabled, text in various boxes may be populated, etc.
For example:
Some questions might be multiple choice and others require typed input.
The user inputs their answer and clicks a button -- if they get something wrong, they have the option to override the 'wrong answer' judgement and say it was really a different, correct variant.
Statistics regarding which questions were answered correctly are kept and used in the decision about what flash cards to show next.
Now the issue.
How do I best create a clean interaction between the "form" code (for example, handling the OK button's onclick command, and enabling or disabling various controls) and the "logic" code (underlying data stores, program logic that does not have immediate implications for display)? If it is all mixed together in the form object code it does not seem right.
Can anyone suggest a design pattern (especially one widely used) that manages this cleanly?
In case it is relevant I am thinking of something like this:
Object Model:
Class MyForm: the form itself.
Class FormController:
Child class of MyForm.
Instantiation requires an object of type MyForm.
FormController's job is to put its MyForm object into a particular "state," by enabling/disabling controls, displaying various text, etc.
FormController exposes a small set of public functions which deal with semantically high-level request for the form state (such as "DisplayNewQuestion(QuestionData d)")
Class Session: Contains all underlying persistent data or objects involving this session, including lists of possible questions, objects that select the next question from the list, etc.
Class Driver: Drives both the Session and FormController objects. For example, it would ask the Session object for a new question, and pass it to the FormController object to update the form.
The advantage to something like this is that icky form code and nice logic code are now completely separable. But is it worthwhile? Are there better or more common design patterns for this?
Thanks a ton!
I am always most comfortable with Model View Controller in this situation. The Shade Tree Developer wrote the most informed series I have ever read on the subject, see here
The jist of MVC is
Model contains the data to be displayed
View is your form and only has logic for displaying and informing of user interactions
Controller contains the glue to make it all happen, including the business logic.
The depenencies should be
Model doesnt know about the view or the controller
View knows about the model and knows how to extract data from it to display
Controller knows about the Model and the view, instansiates them both and wires them together.
The model raises an event when it changes, the view captures this event and refreshes its display accordingly.
The view raises an event when a user interaction occurs, the controller captures this event and performs the correct action for the interaction whether that be updating the model or saving or clearing or whatever.
The view should not write to the model itself
You will see a lot of code where the form creates the controller but imo this is wrong. It came about because of people trying to apply this pattern in asp.net webforms where you have no control over the lifecycle, the first thing that always got created was a view so you had no choice but to have this create your controller, however in winforms you are in control, so make it clean, have the controller create the view.
You might want to use the Model-View-Controller (MVC) design pattern, in which the "logic" is your controller and the "view" is your UI. The model is used to access and retrieve data from your data source (a SQL database for instance)
It is worthwhile to separate your logic from your UI, because it makes them more maintainable. For example, if you want to change your UI from a winform to a web page, you don't have to redo all your logic.
Also, it makes up for a really cleaner code. Using design patterns in general helps other programmers understand your code faster as well.
I want to create two diffent types of DockPanels. If the user clicks on one link, it loads DockPanel #1 otherwise it loads #2.
Can we dynamically swap them? I'm new to WPF. In REALBasic, I'd use GroupPanels and I'd swap them if needed.
Thanks
U can dynamicly create controls and fill their content with other controls. Or u can just place both types and hide one u dont want to show.
Take a look at Josh Smith's MVVM Article in MSDN Magazine. Josh is considered by many to be The MVVM Guru, and this article does a good job at explaining the basics.
With that in mind, I would probably do your app as an MVVM application.
The Model would "just" be your data model (much like in MVC).
Next there would be a View for each of your panels. Each View could either be set up as a DataTemplate (like in the article), or as a UserControl (as I've done and seen done many other places as well). Doing so makes it modular, and easier to expand, maintain, etc.
Your MainWindow is really also considered a View, onto which you place other Views.
All of the Views will be controlled by one or more ViewModel classes. How many you have depends on your design. Generally, if there is distinct functionality, you will have a more-or-less one-to-one relationship between a View and a ViewModel (although you can certainly share multiple Views with a single ViewModel). There will also generally be a single "Main ViewModel" class to hold everything together.
In general terms given the general description of your problem, it is likely that your ViewModel will contain a Command (or Commands), handled when your user chooses a link. This Command will likely set some property, which will control which View gets shown (usually via Binding).
Sorry I can't get more detailed than this, but if I did I'd need to know more about your design, and I'd have to write a lot more stuff, which isn't really appropriate in this forum.