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
Related
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.
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've read MEF documentation on Codeplex and I'm trying to figure out how to accomplish my task:
I would like to build an application framework that has standard components that can be used to do some common work (like displaying a list of records from a database). Plugins should be reused many times with different configuration each time. (eg. I have 5 windows in an application where I display record lists, each with different type of entity, different columns, each one should have it's own extension points like for displaying record details that should be satisfied with a different copy of another common plugin).
Is MEF suitable for such a scenario? How should I define contracts? Should I use metadata? Can I define relationships using configuration files?
Yes, you can use MEF. MEF supports NonShared instantiation of objects using the PartCreationPolicy attribute:
[PartCreationPolicy(CreationPolicy.NonShared)]
More information on this here.
Personally I'd do the wiring and configuration after the importing of the component on the target. However I am not sure how generic you want your application to be, if you are making a 'framework' to do certain solutions in I can imagine you want the configuration to be separate. You can go all-over-board and make an ISuperDuperGridConfiguration and import these on the constructor [ImportingConstructor] of your grid plugin. From within your target (where the grids get imported) set the location of the grid to the grid plugin (like main grid, side grid) and use the data stored in ISuperDuperGridConfiguration to further config the grid plugin itself.
However, you can easily go 'too far' with MEF, depending on your goals. We have a completely MEF componentized UI for an application with customized needs for every single customer. Sometimes I have the urge to put single buttons from the ribbon in a MEF extension.
As you can see, depending on your needs, you can and sometimes will go too far.
I don't think you'd need metadata especially in your case, but maybe someone else can share a different opinion on this ;-).
I hope this answers your question, if not please comment so I can highlight more aspects. All in all using MEF has been very positive for us, and we are using it far beyond a 'hello world' so to say. So at least you have that!
The project I'm working on is quite large and we have a framework we developed for building simple UI screens easily. The two fundamental types we have are Search (search parameters + grid of results) and Detail (a set of editors that are usually populated from some model object).
The application is all C# .NET Winforms.
In the Detail we have the following process.
Load - Populate the edit controls based on the appropriate model object. Invoked just prior to the Detail being shown
User clicks ok
Validate - Validates the detail to ensure everything is consistent
Accept - Copy the updated control values back into the model
This all works nicely for simple stuff but in more complex cases I've noticed perhaps the above approach is not the smoothest.
The more complex cases mentioned above are when a Detail represents a model object and there is a grid embedded in the Detail which holds 'child' objects which can be added and removed. Typically you want to launch the child Detail and pass in the parent model object, however it is not fully populated/up to date at this point because that only happens when OK is clicked. I find myself working round this in an annoying fashion sometimes which leads me to the following question.
At a high-level, is the accepted/best practice approach for Detail screens like I describe to copy values to the model object when the control is changed, rather than waiting until OK is clicked?
If so, in a Winforms app, what is the best way to achieve this? I found some articles mentioning Control.DataBindings but it's not ideal because of the lack of compile-time safety on the binding. I've read WPF has good binding support, but unfortunately, I'm not using WPF.
For Winforms I would suggest that you look into the Model-View-Presenter pattern.
http://msdn.microsoft.com/en-us/magazine/cc188690.aspx
This might help:
Walkthrough: Creating a Master/Detail Form Using Two Windows Forms DataGridView Controls
http://msdn.microsoft.com/en-us/library/y8c0cxey.aspx
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.