I am working on a project in C# with many complex UserControls. Things like tanks, valves, pumps, gauges, etc. A view can have anywhere from a couple to 40 or 50 controls on it. I will ultimately have hundreds of views made up of these Controls. (I am generating them programmatically from old versions of the screens). The problem I have run into is creating a ViewModel for my views. I can not make a static ViewModel for every page. I need to dynamically create a ViewModel based on the controls contained in the view.
I am able to find what controls are on a view and create a model for each but I dont know how to create a ViewModel which lets me bind to those models without creating a ViewModel for each individual control.
Any help or advice would be appreciated, Thanks!
I think I was able to solve the problem. My ViewModel has a Dictionary with a unique Identifier as the key and the Model object as the value.
I go through the controls on a view, create a model and add it to the VM dictionary. My Binding is to the dictionary as such:
Vm has a dictionary called Models:
Dictionary<string, Model> Models;
View
{Binding Models[KEY].Property}
Related
I have an app that should display data based on variables from parameters received from calls of the ViewModel.
I have noticed two places in which the ViewModel gets called from, one is the intended call by the parent ViewModel for displaying the View of the child ViewModel with the help of ViewLocator.cs. Another is the DataContext required by the View to enable data binding.
Former: [ParentViewModel.cs]
public ParentViewModel()
{
UserControlContent = new ChildViewModel(genericParameter: "actual parameter");
}
Latter: [ChildView.axaml.cs]
public ChildView()
{
InitializeComponent();
DataContext = new ChildViewModel(genericParameter: "not the parameter I want");
}
So I want to pass in the "actual parameter" as shown above for show in the resulting View. I expect the final view to look like this:
But in reality I get this:
So, how can I work around this and get the View to display the right data?
Appreciate any input!
Turns out, only the call from the ParentViewModel is required. DataContext under ChildView can be removed and the correct parameter can be used.
Thanks to the answer here for this question.
I think you have some fundamental misunderstandings of MVVM.
Firstly, you have two ChildViewModel instances.
So calls made in your ParentViewModel on the UserControlContent instance of the view model will never be reflected in the UI as the ChildView creates a new instance of the ChildViewModel itself and then uses this instance for as it's DataContext.
You should make use of some form of IoC and DI your dependencies.
MVVM discourages the use of manual view model creation through the new keyword.
Unless there is a very specific use case, try to keep some relationship between the UI structure and your view models as flat as possible.
By this I mean if there is a use case where the parent view model needs the same things as the child view mode. It may make sense to flatten and merge those two view models.
This in turn simplifies the VMs themselves and the bindings.
I have a WPF, MVVM program whose MainWindow is separated into a ListBox sidebar and a main part with a ContentControl. I want to create a functionality that will populate the ListBox with a button for each view that I have in my project and set its command such that clicking it will set the content of the ContentControl to the associated view automatically, i.e. so that I don't have to manually enter code when adding a new view. Something like iterate through all view files or something like that.
EDIT:
Perhaps I'm AGAIN not clear enough.
What I have and can do - type like a monkey "new Button, yadda yadda" every time I add a new view to my project.
What I want - write a piece of black magic that goes something like "There are 6 views in this project, I'll just make 6 buttons each such that, when clicked, will navigate to the appropriate view, without the guy who wrote me having to write any additional line of code any time a new view is added".
How can I achieve that and is it such a good idea, to begin with?
For instructional purposes, I'll be calling your "view" class View.
Create some sort of collection object (List<View>, ObservableCollection<View>, etc.) to store all of the Views.
Assign this collection to a dependency property. I'll call it Views.
Declare a dependency property for the selected/active view. I'll call it SelectedView.
Bind ListBox.ItemsSource to Views.
Bind ListBox.SelectedItem to View.
Bind ContentControl.Content to View as well.
With the above setup, the ContentControl will display whatever View is selected in the ListBox.
I have a View for Insert an entity.
I want to edit the same entity and I want to reuse the same view for edit.
Now, How can I reuse the same view with different ViewModel for edit?
I assume you're using the ViewModelLocator, otherwise you wouldn't even have to ask the question.
So drop the view model locator here, navigate to the view model you want (InsertViewModel or EditViewModel) and assign the same view to both view models via data template.
Why do you need two different view models?
Just merge the properties in one viewmodel.
Or better still, break the view into different UserControls for each view model.
I need some help about MVVM pattern.
I created a ViewModel that expose data and commands to be displayed in a listview in a View named A.
This ViewModel is also used in a view named B. In this view, i just need to expose some properties and no commands but i had to create 2 more properties.
Is it better to create a more specific ViewModel for View B even if it concerns the same object?
I would suggest composition, have two view models which both have a property containing a view model that holds the common properties. The two view models should then only have their specific other properties and commands.
Difficult to answer. But i can tell you what we do for our application. We have one viewmodel, which is more or less view independant, it just functions as a wrapper for our business data and contains all the stuff that is used in almost all parts where this model is shown. Now for the view part, we have very specific viewmodels. Like a ProjectTreeViewModel or a SearchResultViewmodel, with the corresponding Item viewmodels for both of them. The Item viewmodel doesn't need to implement all the logic again, it just needs to agregate the general model view model.
To give a better analogy:
If you have a File, Drive and Folder model. You would create a FileViewModel, DriveViewModel and FolderViewModel. But only one ExplorerItemViewModel. This only needs to provide a property to expose the underlying view model. The rest is depending on your data templates.
i am writing an application that has a viewmodel and a usercontrol that displays
data from this viewmodel. The viewmodel contains an entity "Appointment", and those
appointments have a property "UserName".
When I display the appointments, I want to use a value-converter to get a color for
the user (depending on "UserName"), but the colors are not contained in the entity "Appointment", so I wanted to create a value-converter that uses the entity "User" from the viewmodel.
What is the best way to use another entity from the viewmodel inside the converter?
Is it possible to access the viewmodel from the usercontrol? I tried to place the converter inside my viewmodel-class, but can I access this class from the usercontrol?
I figured out that the following possibilities might work:
Adjust the viewmodel so that each appointment also contains the color. But I don't want to do this because I don't want to mess with the viewmodel.
Set the converter-parameter from the class that also contains the viewmodel at startup. (Does this work?)
Use x:Reference to databind the converter parameter to the viewmodel that is unknown at compile-time.(Is this possible?)
Converter parameter is the way to go.
Why is the viewmodel unknown at compile time?
Bindings are not compile time checked anyway.
Is the UserControl.DataContext being set to an instance of Appointment, you should be able to set the parameter to {Binding UserName} or {Binding Appointment.UserName} depending on exactly what you are setting as the DataContext on the UserControl.
I would suggest that you re-examine your reluctance to modify the view model. The purpose of having a view model in the first place is so that everything that the view needs can be found in one place. Coming up with elaborate value converters to prevent modifying the view model is an approach that gets increasingly unmaintainable the more you do it.