Using INotifyDataErrorInfo with embedded UserControl in WPF (with Caliburn.Micro) - c#

I have inherited some code for a fairly complex WPF application which uses Caliburn.Micro to implementt the MVVM pattern. It uses views bound automatically to view models using the Caliburn naming conventions. The view models inherit from a class that implements INotifyDataErrorInfo, and Fluent Validation is used to generate field-specific errors. This works perfectly, except in one scenario where I have a user control embedded into several different views, and the UI elements within that user control need to be validated.
The embedded user control has it's own view model, which doesn't implement INotifyDataErrorInfo. Suffice to say that the validation messages we generate when validating the parent view do not propagate up to the UI for display.
I'm not quite sure what code I would need to show here to illustrate the problem, so the question is more conceptual really - the question is:
Im my scenario, should I be implementing on the view model behind the embedded user control, or is there some other way to make the parent view call GetErrors() on it's view model with the property names of controls nested within embedded user controls?
I hope that makes sense - I'm quite new to WPF!

I ended up solving this. The problem turned out to be that I had a separate view model bound to the nested view, and that view model did not inherit from a class that implemented INotifyDataErrorInfo. Suffice to say that the rule here seems to be you can have embedded user controls which have their own view model (datacontext) and still get the validation behaviour, but every view model in the hierarchy must implementINotifyDataErrorInfo otherwise the UI elements bound to them won't get notified of errors. In my case it was difficult to see problem because Caliburn.Micro and AutoFac were doing a lot of auto-wiring that was hard to see in a debug context.

Related

Best way to split huge view model/xaml

I’m refactoring a big view model and it's associated XAML page. I use Prism. The main page has a clear functionality, create an avatar. There are steps to create the avatar like take the picture, edit the picture, etc. I have now a detail side bar which controls the navigation for the steps and a main content area which I show different content depending on these steps. I hide/show the appropriate views depending on the step. The project grew and now I have a 2000+ line view model and a huge XAML file.
What I ended up doing after some research is creating ContentViews for each step (showing and hiding them for each step again), so the XAML get's modularized for each step and also a View Model for each step. I was successful in binding the ContentView to each ViewModel but now I have problems communicating the different View Models information.
As before everything was in the same View Model, all views could share the same bound properties if needed. Now, as each view model is independent I need to find a way to properly share this information. My first approach was to use the Messaging Center. This way I can send the information i need to share to the view model that manages the navigation between steps (NavigationViewModel) and this can send this information to the following view models.
The thing is that I don't really like this solution as I find it too complex and will end up with a lot of code in the NavigationViewModel to subscribe/send to each sub-viewmodel to pass the shared information.
So my question is, do you know any other way to ease the communication between the view models?
I even thought about using partial classes to 'hide' my big view model complexity, but I think this is not a good idea.
Recenlty i came across the same problem,my ViewModel became really huge(with hundreds of properties) .So what i did is :
Created an Interface class.Putting all the common properties in there.Let's say IA.
Created another class inheriting IA.
And now multiple classes are inherting IA,reducing the overall properties numbers.

Quick way to create/check Views against ViewModel properties?

I'm working on a MVVM project where I'm using Caliburn.micro. The problem is that, I have my ViewModels in one folder and my Views in another. Also, I have about 20-30 properties per ViewModel and about a dozen ViewModels and growing. Is there any easy way to translate my string/int Properties to Textboxes and BindableCollections to ComboBoxes? In other words, is there any tool to generate a View automatically from ViewModel? If that is not possible, then is there any tool to check whether there is a control in the View that binds with a Property in the ViewModel? Frankly, creating Views by hand is quite tedious and is prone to errors.
Seems like a duplicate of generate viewmodel from model?.
New link to the tool is https://marketplace.visualstudio.com/items?itemName=KarlShifflettkdawg.XAMLPowerToysforVisualStudio2015.

Creating a wizard in wpf

I'm currently creating a "wizard" to create new projects inside my program. I have a solution that is almost done but it doesn't feel "right" and start to think about other solutions. Maybe should note that I also use MVVMLight.
My current solution:
I have a window and the window contains custom user controls (they represent every page of the wizard).
Both the window and the user controls share the same view model
When you click back/next the view model handles which user control that should be visible
The problem with this one is that I don't like the shared view model. I have a shared view model because all pages configure different things on the same object and it's easier to follow. But at the same time thew view model contains a lot of things that each individuell user control doesn't need (for example only one page need methods to add/edit filters). It also makes it hard to re-user the user control later if I want them for something else than the wizard.
So should I instead create diffrent view models for the window and each user control and send messages between the view models with MVVMLights MessengerInstance? I feel that's cleaner but as a reader it's maybe harder to follow (something I feel in general when I sending messages around)?
With messenger it would be a workflow like this:
User enter all the information on a "page"
User click on next (that belongs to the window)
The windows view model have to send a message to the user control to check if all the data is valid
The user control check the data and have to send back if it's valid or not. If it's valid tell the next page to get visible, if not show error message.
So it would be a lot of messages back and forth that I don't need with the shared view model solution.
Or is there a better solution that I should do?
I would expect that the answers you receive here are primarily opinion based, but here goes anyway.
Currently, your view model has more than one responsibility, and therefore, more than one reason to change. It's certainly a good idea to split up your view models into smaller, more manageable classes. This may appear to reduce readability, however I would disagree. The idea of ensuring that classes only have one responsibility keeps things simple and promotes re-use.
That being said, your main view model will most likely hold references to many other child view models, but this isn't the end of the world, in fact, it's a good thing. The parent-child relationship between your view models is much like the parent-child relationship in your views. For example, a Window contains many UserControls, there's nothing wrong with mimicking this relationship with the view models.
Now, there are of course a few ways to communicate between view models. I personally prefer to use events, where a child view model raises an event that the parent view model subscribes to. Pretty simple, really. Although there is some degree of coupling in this scenario, you could of course abstract your classes away into interfaces and use dependency injection to inject them into the parent view model. Using events is down to personal preference, however MVVMLight has quite a nice MessengerInstance that decouples view models even further.
So. My suggestion:
Work out the responsibilities of your view model.
Split up the massive view model into smaller view models (based on the responsibilities).
Create a parent-child relationships between view models. Your view will in fact point you in the right direction in terms of the relationships.

What are my controller in my application with a MVVM design pattern

I have developed a WPF-application. I have a mainwindow which inherit from Window, a tabcontrol and many tabitems in this tabcontrol which inherit from UserControl. Every tabitem has its own cs-file, where I code in C# all the businesslogic, and a XAML-file where the development of the UI is done. I also have a SQL Server with a database which i connect to trough LINQ.
So i have to write about my choice of which controller i use in my application. This is where i get confused, since i havent manually programmed a controller and i thought the ViewModel would behave like a controller in my case. Could this be correct? Can the ViewModel behave like a controller?
A controller can send commands to its associated view to change the view's presentation of the model (e.g., by scrolling through a document). It can also send commands to the model to update the model's state (e.g., editing a document). Model_View_Controller
The viewmodel is a “model of the view” meaning it is an abstraction of the view that also serves in mediating between the view and the model which is the target of the view data bindings. It could be seen as a specialized aspect of what would be a controller (in the MVC pattern) that acts as a converter that changes model information into view information and passes commands from the view into the model. The view model exposes public properties, commands, and abstractions. Model_View_ViewModel
The introduction of MVVMC (MVC + MVVM) is nessesary in cases you would like to drive many similar pairs of View-ViewModel (use cases). You can then introduce controllers. Model_View_ViewModel_Controller
In the simplest case, have the ViewModel implement the "controller" logic. For large applications, I sometimes use an MVVMC pattern which uses a separate controller class. There has been a lot of recent support on the blogosphere for using MVVMC over MVVM.
MVVM is dead, long live MVVMC!
MVMMC – MVVM grows a Controller

Keeping Control and Data loosely coupled in Silverlight?

I have separate library (Controls.DLL) with my custom Controls.
I have another library (Model.dll) with my data access code.
Some controls do need access to data. I'd like to keep those libraries loosely coupled. Basically, I'd like to acces data without referencing Model.dll
What is the proper way to do it? Naturally, I think Binding is a way to go. But it's not just binding to data, I also need to execute actions against my model (retreive data, paging, filtering). And I need to study metadata that my model contains.
For example, I have Customer class with properties like "FirstName", "LastName", etc. But I want those to be displayed inside my control with captions like "First Name", "Last Name". This is primitive example but it kind of shows my point.
My other idea was to have "providers" on data side that would spit out XML and on control side I will parse this XML. But how do I go about methods?
Another idea is to go with reflection. This way I would just pass object to Control. But I'm not as good with reflection and not sure if I can achieve things like: getting properties/attributes. Getting and executing methods? This sounds like a perfect thing to code with Interfaces but Interface need to live somewhere and therefore something have to reference something.
So, what is the best way to code loosely like this?
Check out the MVVM pattern (Model-View-ViewModel).
Basically, a ViewModel wraps a Model, and exposes data access and data manipulation commands to the user interface (the View) via property bindings.
You'll find heaps of documentation, tutorials etc. by searching for MVVM. Or check out this StackOverflow answer to get you started.
Update:
MVVM allows you to separate custom controls and data. It sounds like you want to dynamically generate interface components based upon data in your model. You can do this in MVVM (it's not the only way, of course). The view model can dynamically generate collections based upon the model. The view model can include methods for converting raw data to display data. This means neither your model or controls (view) need to know how to
do this.
Depending on the nature of your data, you may choose to have `generic' view models reflect over property names to procedurally generate display names (as in your primitive example), or you may choose to write specific view models for specific data in your model. That will depend upon the nature of your data. Either way, your custom controls (in the view) remain decoupled from the model.
Update 2:
Your view models do not need to live in the same assembly as the view (controls). You can even put them in a third assembly (as described here). Of course that encourages you to follow MVVM more strictly and make sure you have no dependencies from ViewModel to View, but that's a good thing. There are a few more hints on the issues related to hooking up views to view models you may encounter here.

Categories

Resources