I am new to WPF having previously worked with WinForms on occasion and I still trying to get my head around the WPF mentality, which given my background is embedded coding, seems quite removed.
In my project I need to create a Grid Panel "template", which I'll call "Fred" (where in this case Fred is simply a cluster of graphically customized buttons) and spawn multiple instances of this to the UI programmatically based on external events. I am finding it hard to see an obvious way to do this (perhaps that is because there maybe multiple ways?) and have looked into ControlTemplates, Styles and Custom Elements. I suspect the solution lies in the latter but I am also concerned I might be thinking about this in the wrong way. To me it seems to make sense to visualize Fred as a Grid resource that I can programmatically invoke somehow when I need to create a new instance, but given I found it hard to "google" this very thing then perhaps I am going about this all wrong?
I apologies if this is a bit vague.
My question here is two fold:
Is this a sensible way to achieve my end goal i.e. if I need to programmatically spawn this cluster of customized Buttons (Fred) then does it make sense to contain these in a Grid that can be accessed by the main C# or is there a more standard way that I am missing to achieve this?
Depending on the answer to (1) are there code examples to achieve this?
The concept you are looking for is an "ItemsControl" (which is itself a usable class, and also has several derived classes like ListView and ListBox) in combination with DataTemplates.
In this case you would make "Fred" a DataTemplate (commonly as the direct descendant of your ItemControls ItemTemplate property in XAML). You then bind ItemsSource to a collection (should be ObservableCollection<T> for runtime additions/deletions).
All of this relies on using the MVVM pattern (which coming from WinForms you probably aren't). I would suggest looking at MSDN, Stack Overflow, an excellent blog series by Reed Copsey: http://reedcopsey.com/series/windows-forms-to-mvvm/ or just google "WPF and MVVM" to learn more.
To answer your questions explicitly:
Yes; you have the right concept but are thinking about it in WinForms terms/practices. Use MVVM instead.
Yes; there are many resources available.
Related
I implemented a file input mask as a user control that I want to re-use in my WPF application in two different contexts.
While the view (in the two cases) is actually pretty much the same, the ViewModel and the logic I implemented there is quite different.
I have already tried to inherit from a common AbstractFileInputView together with an abstract ViewModel, but that seems to break as soon as I put it in XAML.
Since I wasn't able to find some actual documentation about how to build re-usable (abstract) user controls, I am wondering if somebody has any hints on how to solve this?
Or do I really just have to go on a copy-and-paste spree here?
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.
I'm starting to develop a WP7 app with MVVM Light. I want to make use of the pivot control to show two different lists of different item types. Would it be best practice to create the PivotItems as UserControls or should I stick everything in one viewmodel?
I think there is no "correct" way to do it, it just depends on your vision.
Personnally, I always create separate UserControls to act as PivotItems.
The main objective is to make my code clearer, with more separate classes it is way more easily unserstandable!
However it also depends on the complexity of the items. Don't feel forced to create one UserControl per item, just separate if the control is quite complex and requires quite a lot of XAML lines, it will clarify your code
I'm still new with C#, and I'm working on a project where we also use WPF, and the WPF DataGrid Toolkit (See at CodePlex), which hasn't yet been released into the framework. Due to the nature of the project, it's 100% sure we will be altering some controls of the assembly later.
My co-workers have decided to redefine every control from the datagrid within a namespace of our project, and ihnerit the specific control of the assembly namespace.
So instead of using:
clr-namespace:Microsoft.Windows.Controls.Primitives;assembly=WPFToolkit
clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit
We'll be using our own xxx.Controls and xxx.Controls.Primitives Namespaces.
This way, it would be pretty easy to alter the ihnerited controls.
Somehow, I got a bad feeling about this solution, but I'm still inexperienced and cannot tell if such an approach is legitimate or not, or if there is another good solution to our requirements (altering the controls later without changing too much code in multiple files).
It would be nice if you express your opinion to this approach.
What kind of alterations are you talking about? It seems like a waste of time to pre-emptively derive from each of the classes before you know what you'll actually need to change.
When you do need to change something, it shouldn't be too hard to create the derived class at that point, and fix up any references - which may only be for some instances rather than all of them. Yes, it may mean check-ins involving quite a few files - but if you're using a sensible source control system it will be an atomic change, and it will be obvious why it's changing.
With your current approach, there's no immediate "these are the controls we've had to change" - if you do it in a "just-in-time" manner, you'll be able to tell just by looking at what derived controls you've actually had to create.
I agree with you. The alterations, or better said, the changes, can be of any kind. Behavior and etc. And the changes should be make just in time.
Unfortunately, that is not my decision. Some stubborns are at work :)
But what is interesting me is if a complete different approach to the whole idea exists?
Say, I've got a DataGrid, the project evolves, and now, I've got to do some drastic changes in the validation behavior of dataGrid rows.
This could also apply to a lot of controls.
The problem with our project is, we have a kind of complex data access layer, which not only provides data, but also actually controls it. This means data isn't read,modified, deleted or appended without including some logic provided by the data access layer.
For an example, the datagrid doesn't directly delete rows, but instead, we overwrite the delete behaviour and aks the data access layer to delete it. With binding, this works pretty good for now.
This kind of scenario will apply to a lot of other things in the future, regarding CRUD operations, validation and etc.
The more I learn about WPF and XAML, the more I realize that you can do pretty much all of your GUI initialization and event handling glue in either XAML or in code (say C# code or VB.Net code).
My question is to those who have been working on WPF for longer and ideally those who have shipped apps with it -- where did you find was the best place to 'draw the line' between XAML and code? Did you use XAML wherever you could? Only where interfacing with non-coding UI designers?
Any tips in this area would be extremely helpful to myself and other coders who are just getting into WPF programming and are kind of paralyzed by all the choices we can make!
One thing that I would look at is the model-view-view model pattern. It is a very elegant pattern which naturally separates everything into nice buckets ... including your xaml.
For example, it helps you keep a clear boundary between the developer and the designer and even allows for test driven development.
There is a whole bunch of info out there on it, but I would start with John Gossman's blog posts:
http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx
http://blogs.msdn.com/johngossman/archive/2005/10/09/478894.aspx
http://blogs.msdn.com/johngossman/archive/2006/02/26/539598.aspx
http://blogs.msdn.com/johngossman/archive/2006/02/27/540304.aspx
http://blogs.msdn.com/johngossman/archive/2006/03/04/543695.aspx
http://blogs.msdn.com/johngossman/archive/2006/04/13/576163.aspx
Update:
Just want to point people to another StackOverflow post with lots of good info on M-V-VM in it.
One tip is to not declare event handlers in XAML. Instead, name your elements and attach events handlers in the code-behind. That helps keep a clean separation between the designer and developer.
As others have suggested, try following the Model-View-ViewModel pattern. However, it's OK to put stuff in the codebehind! The rule is that if it's "View" related, you put it in the Xaml or the codebehind (whichever is more convenient for you). If it's more business logic related to how the user interacts with the system, then it belongs in the ViewModel. If it's just business logic not concerned with interaction, it belongs in the Model.
Examples of each would be:
Model: defines a property called ModifiedDate that stores the last time it was modified.
ViewModel: converts the ModifiedDate into an enumeration property called ModifiedAge, based on when it was modified: Yesterday, In the Last Week, In the Last Month, In the Last Year, etc.
View: converts the ModifiedAge property to a background color where more recently accessed data is highlighted bright yellow, and less recently accessed data is more of a beige-khaki-gray that your designer insists is called "Meadow Lark Lilly Flowerpot".
Another tip is to separate XAML into functional and aesthetic. Developers would typically work in the functional XAML whilst designers care primarily about the aesthetic. This keeps the functional XAML very easy to grok, which is important because developers often need to edit such XAML. Aesthetic XAML is typically edited by designers using tools, so its neatness and verbosity is less of an issue.
I did a bit of a blog post on this a while ago here.
Don't lose sight of the fact that XAML is code. It's declarative and all that, but it's still a programming language. In fact, it goes through a conversion to C# or Visual Basic before it's turned into IL for the .NET compiler to chew on.
I'll echo Scott Whitlock's comment: MVVM is a great way to separate concerns and focus on architectural details. It's really, really OK to put stuff in your code-behind, especially the stuff he describes. If you don't have a requirement to separate designer from developer, then adapt the MVVM pattern to your specific needs; don't try to force yourself to be pure or idealistic about it.
It's also perfectly OK to put calls to your ViewModel's methods right in the View code behind, if you don't need the flexibility of commanding with ICommand classes. Or if you know the View you're making will always be bound to the ViewModel class you're making. Or you could take things a step further, define an interface for your ViewModel, and bind only to implementations of that interface. Then you can still swap out the ViewModel whenever you want.
Stuff like that.
When you follow a proper pattern like Mode-View-ViewModel you will get opportunity to do more on XAML side and less on code behind. Maximize the usage of RoutedEvents and Commands in WPF code.
When building UserControls I try to Xamlize as much as possible.
One tip I found in the field is that creating ControlTemplate and DataTemplates by hand is really a pain in the ***... I always write those in XAML....
I would say use as much xaml possible, using Binding, commands, styles, templates etc. I had to support functionality of saving and loading templates using XAMLReader/XAMLWriter and it more easier for controls having more xaml.