I have done quite a bit of research in the last few months and haven't been able to really find a good answer for my question yet:
A little background info: I am new to WPF and was asked to create a project using it. I learned most of the concepts on my own, but am struggling with one major issue. There is just too much code in the MainWindow class.
The reason there is too much code: There is too much code because all of the events for my UI Elements must be controlled in this one class.
Now I just recently discovered the use of partial classes. So I plan to split the events off into a seperate file. I am just wondering if there is any better way to decrease the size of my MainWindow class? I haven't been able to find a way to pass controls between classes, because I know it is not good to pass TextBoxes, or ListBoxes etc. between classes or methods. (I do understand, however, that you can pass parameters such as textBox1.Text or similar properties, but that doesn't fix my issue.
Introducing partial classes will not make your code any better, it will just spread the bad code over different files.
The "standard" way of developing WPF applications is to use the Model-View-ViewModel (MVVM) pattern. Using this enables you to have XAML-only views, view models that control their behavior and models that provide your application data.
There are tons of tutorials on this on the web. MSDN has a good introduction to this pattern. Having read this you should have a good overview of MVVM and can start applying it to your application.
Related
I am having a hard time understanding how MVVM is used in case of more complex applications. All the examples I can find are extremely basic Apps.
Let's say I have a "Package Delivery" application. To perform a delivery I have to do 3 steps:
Scan the package
Enter any damages or problems with the package
Let the recipient sign on the device
All this information gets validated on the device and then sent to the backend.
In MVC I would implement this like this:
The DeliveryController handles all of the logic. This includes navigation between pages, fetching of API data and validating all of the data once it is all collected.
The controller acts as the "Connection" between the Views and collects all the information and brings it together.
But how would this be done in MVVM? Where would all the data be brought together? Most implementations of MVVM I can find do something like this:
In this, the data entered in each View would have to be passed to the next ViewModel until the end of the chain is reached. At that point the SignatureViewModel would do the validation and make the API call. That seems very weird and like it would get very confusing, since data would just be "passed through" multiple ViewModels just to have it at the end of the chain.
Another option I see would be that each ViewModel handles it's own data:
Here for instance the DamagesViewModel would validate and send the data it's own View handles. The big issue with this is that data does not get sent as a whole. Also there can not be any validation of the entire data before it is sent.
My last idea would look like this:
This adds a DeliveryViewModel that essentials acts like the DeliveryController does in MVC. It would handle which ViewModel to navigate to next, handle what API calls to make and validate all the data once it is entered.
To me (as someone who has mostly used MVC) this last options seems most sensible. But I also feel like it might miss the point of MVVM.
How is this usually done in MVVM? I would really appreciate any pointers. Links to articles that explain this well are much appreciated.
Also if anyone knows of any publicly available repositories or projects that have this kind of pattern in them, I would love to see them.
Even when using MVVM I still use some form of a controller and consider ViewModels as basically transformation of data to facilitate the view.
So for me there is still a service or controller layer that completely separates the middle and back end tier from the rest of the architecture.
View models come into play depending on the consumer/app - fetches data from the service tier, transforming the data, validating etc for the purpose of a consumer/app/etc.
I have struggled quite a bit with the same thing. Especially since I’ve used MVC quite a lot.
I think the most important thing to consider is that MVVM is not meant to solve exactly the same things as MVC. You can still implement a controller outside of this pattern to complement it. It also changes quite a lot the general design of the application.
One mean to do it that I have used is to implement the controller as a singleton that can be shared between VewModels. This controller can per example be injected into the ViewModels using dependency injection.
Viewmodels could then for exemple subscribe to events coming from the controller to update.
But this is one way to solve this problem among others.
MVVM is a way to organize code. It’s one way to separate your user interface from your logic.
I have found a blog where you can have a look where MVVM architecture is described perfectly.Though here writer demonstrates MVVM for windows form app but at least you can get some idea about architectural design of MVVM.
https://scottlilly.com/c-design-patterns-mvvm-model-view-viewmodel/
Also please have a look into this repo.
https://github.com/MarkWithall/worlds-simplest-csharp-wpf-mvvm-example
I'm creating a simple WPF application for practice purposes only, but I have little experience in WPF. Using WPF XAML seems troublesome to me, as I have a lot more experience with C# Console and especially with the C#- and JS-driven videogame engine Unity, where devs have access to an Editor (analogous to the Design Window in WPF) and the code behind, with no XAML whatsoever. This is why I tend to use less XAML and much code behind.
For example here, I modify the Margin property of a button, while I set its Opacity to 1; this all happens upon a click event to the grid, which calls the function (exactly the way it's done in Unity):
public void Grid_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
RandomButton.Margin = new Thickness(0, 0, 0, 0);
RandomButton.Opacity = 1;
}
If I'm not mistaken, this can be achieved through Data Binding in XAML as well, although it seems to be a lot more complicated method seemingly producing the same result.
So my questions are: is there a difference between the two ways, say, performance-wise or in terms of expandability (which one would be easier to expand/modify later)? Which one is used in the industry?
There is no difference as far as the performance is concerned. For any element that you define in your XAML markup, an instance of a corresponding type will be created by the framework at runtime.
It is generally much easier to define the visual presentation of an application using XAML though. This is what XAML is used for after all: https://msdn.microsoft.com/en-us/library/cc295302.aspx
You still use a programming language such as C# to implement your application logic though, i.e. what happens when a mouse button is pressed etc. So setting/modifying the properties of any element that you originally create in the XAML markup using C# is fine.
Which one is used in the industry?
When it comes to enterprise WPF applications the recommended design pattern to use is MVVM (Model-View-ViewModel). You can refer to the following link for more information about it: https://msdn.microsoft.com/en-us/library/hh848246.aspx
The view is responsible for defining the structure, layout, and appearance of what the user sees on the screen and is typically created using only XAML whereas the view model and the model that are responsible for handling the view logic and business logic respectively is implemented using a programming language like C#.
You will find a lot more information and samples of how to implement the MVVM design pattern if you Google or Bing for it.
Hi being a WPF/XAML developer I would suggest you to use XAML as much as you can.Make use of commands and bindings i.e use MVVM architecture. What if you want to set the opacity using keys (example: ctrl+shift) you will have to write another code behind for that making your code redundant affecting performance of your app. Make use of MVVM pattern ( You can use MVVM light by galasoft). As of expanding or modification you will have to modify a single command method rather than modifying each event etc on the code behind. Easy to test ..Easy to build..Easy to modify..
I have a winforms app, I use a mix of standard controls and Syncfusion controls currently. In a few months or so new modules will be developed in WPF.
I'd like to add some state saving functionality. You know. TreeView x's last open node was y. Splitter X was split to point Y and so forth.
I've seen a few approaches. I've seen using the built in application settings and how to bind that to winforms and WPF. This has issues when your application is modular or the GUI is dynamically created.
I've got a few approaches in mind. I'd sort of like an approach which mirrors Entity frameworks POCO approach. I don't really want to be decorating my GUI code with attributes or deriving it from a special base class that knows about gui persistence, or implementing ISerializable, etc.
Saying that, I'm also considering using attributes to decorate the gui components and sort of duplicating a lot of what the serializable code in the framework already does, but specifically geared towards GUI settings. I also considered just using the serializable stuff, but it doesn't reflect my intent accurately.
Does anyone have any advice they can give on this?
Thanks
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'm working on a WPF MVVM application. The thing that I'm noticing is that I have to write an inordinate amount of boilerplate code just to declare commands (through DelegateCommands from the WPF Team's MVVM Toolkit), attached properties and attached behaviors. Are there any strategies available to reduce the amount of boilerplate code I have to write?
Thanks!
Personally, I like Josh Smith's MVVM Foundation library. He uses a class called RelayCommand there, but it sounds pretty similar to your DelegateCommand from the toolkit. It lets you create a command and pass the CanExecute and Execute logic through lambda expressions. That will help reduce a lot of boilerplate code.
In his blog, Josh also talks about using a generic property observer to avoid some of the messier aspects of PropertyChanged event handling. That is worth looking into, as well.
Honestly though, a lot of the so-called "boilerplate" code is setting up a very dynamic and flexible foundation for your application. If you are making a small, easily maintained application, you might ask yourself, "do I even need to apply the MVVM pattern here?" If, on the other hand, you are making a larger application that will have a long life-time and require a lot of maintenance, then this boilerplate code is going to save you down the line.
I found that I was writing a lot of code to implement change notification via the INotifyPropertyChanged interface. To reduce this I found a NuGet package called PropertyChanged.Fody that makes adding INotifyPropertyChanged to a classes properties really simple.
Here's how to use it;
using PropertyChanged;
[ImplementPropertyChanged]
public partial class Order
{
}
Now any public property in the class will have property changed notification. This is particularly useful for EF classes generated through DB first where you don't have total control over your entities.
See GitHub for more information.
The most obvious strategy I can think of is using code snippets and/or file templates. It does not reduce the lines of codes but at least it makes you save time.
You can make them yourself(or find some you can import directly to your Visual studio).
I personally use the mvvm light toolkit from Laurent Bugnion and I use his code-snippets/file templates, they do save me a lot of time. I would assume there is something similar for most of the popular mvvm toolkits.
Hope it helps!