WPF/MVVM:Set multiple datacontext to ONE usercontrol - wpf

I have a UserControl with 5 small UserControl which are parts of the first UserControl.
The first UserControl is datatemplated by a MainViewModel type.
The other 5 small UserControls have also set the DataContext to this MainViewModel type.
Now I want additionally that those 5 UserControls get a 2nd DataContext to access other public
properties of another ViewModel .
How can I do that?

I don't believe that you can have multiple DataContexts set for any given control.
So, depending on what exactly you're looking to do, you could:
a) Just set the DataContext for the 5 sub controls to the 2nd DataContext type
or
b) Create another ViewModel that inherits from your MainViewModel and also includes all the extra properties you need for the 5 sub controls. This would be in the case where you require everything from the MainViewModel AND the 2nd view model.
I guess you could also modify your main ViewModel to access properties on a subviewmodel, but this is all quite speculative without knowing what you're actually aiming to do.
Hope that helps :)

Related

WPF use one ViewModel for multiple UserControls

I've searched a lot for an answer for this question, but couldn't quite find an answer.
I have my main Window and 4 different UserControls. The Window is constructed from all 4 UserControls.
I have a class which is the Window's ViewModel.
I wish to set the DataContext of the Window and all 4 UserControls as the Window's ViewModel.
The problem is that writing the class as the control's DataContext creates a new instance of the class, hence, I can't use the containers I'm filling.
Any way of doing that?
DataContext gets inherited in WPF.
If you don't set a DataContext for the UserControl, they will automatically inherit their parent's DataContext (the Window), and should use your ViewModel directly.

Bind DataGrid's PreviewDrop to a command property

I have 2 datagrids in my UI which lists vehicles. Both DataGrids are exactly the same except they maintain 2 different ObservableCollections.
I created a VehicleListViewModel which contains an ObservableCollection property and different ICommand properties. So I have DataGrid1's DataContext set to the first instance of VehicleListViewModel (ViewModel1) and the 2nd DataGrid's DataContenxt to the second instance (ViewModel2).
Now, I need to implement the PreviewDrop for both datagrids. I want to have the code for this inside the ViewModel as well and not in the code-behind. However, setting PreviewDrop="xxxxxx" only allows the event handler to be defined within the code-behind. Does anyone know a way to do this?
EventToCommand Behavior:
EventToCommand
Place this on your datagrid and bind it to a command property in your viewmodel.

How can I easily expose bindable properties of nested controls from a custom UserControl?

My first question here on the Stack. Forgive me for the bad explanation in advance.
I am working on my first MVVM application (Silverlight). I have a custom user control that contains a ListBox to show navigation items. This control is placed in my main xaml page. I don't know if I need to create a composite view model (my main page view model) with a view model especially for the custom control in it or if there is some way to elevate the ListBox properties that I need to bind to.
Through XAML I don't know how to bind, let's say, the ItemsSource property of the ListBox inside the custom control to my main page viewmodel. Basically, I'm at the point that I am questioning my design decision for trying to bind the custom control through my main page view model.
What I have done so far is create dependency properties for the custom control and try to tunnel those dependency properties down to the ListBox properties. I've achieved success with this method for ItemsSource but am having issues with SelectedItem.
Even if I do get SelectedItem to work, it still feels Wrong. Thanks for any advice in advance.
The UserControl should inherit the DataContext from its parent control, unless you are setting it directly. You can then bind to the properties on your view model from your UserControl.
If you would like to create a ViewModel specifically for the UserControl, you can also do that. You would then expose it as a property on your main ViewModel, and bind to it in the MainPage. Example:
public class MainViewModel
{
public ChildViewModel ChildInfo { get; private set; }
}
And then in the view:
<Grid>
...
<lcl:ChildView DataContext="{Binding ChildInfo}" />
...
</Grid>
Your ChildViewModel would then contain properties like SelectedItem to bind your ListBox to.

Silverlight Commands MVVM

I'd like to 'reduce' the number of commands in my ViewModel class.
I have one ViewModel which contains 5+ lists (using Listboxes on View to presentate, and I'm binding an ObservableCollection to its ItemSource parameter; also binding the SelectedItem property), and each list should have its own Add/Remove/etc button.
So, it looks like this:
public class PersonViewModel : ViewModelBase
{
Person _Person;
private ObservableCollection<WorkPlaceViewModel> _WPlaces;
private ObservableCollection<LanguageViewModel> _Languages;
... other lists
private WorkPlaceViewModel _SelectedWorkPlaceView;
...
}
Adding 5x2 command makes the ViewModel a bit large. I could hardcode a string to the CommandParameter and handle it with a switch-case in my ViewModel but this sounds like hacking. :p
Or should I go with creating a Remove command for each listbox, and pass the SelectedItem as a parameter?
Whats the best way for this in MVVM?
Why do you have a collection of viewmodels in your viewmodel? What is the PersonViewModel supposed to accomplish. It sounds to me like you need to break up your view into multiple views and bind them to different viewmodels. Your views and viewmodels should be as small as possible to reduce coupling.
That said, I would recommend commands for add/remove on each observable collection. Using a hardcode string is messy, as you guessed. If each observable collection has their own add/remove that will allow different logic for each collection and is more maintainable.
Can you post more code from your ViewModel and describe the app a bit? That will help us determine if there could be a better design decision.

WPF: How to reuse controls when ObservableCollection is concrete?

I have a object that inherits from TabItem. I have a bunch of Database objects that will reuse the same code so I wanted only one TabItem class and then use DataTemplates to control how each object gets presented.
Problem is that the TabItem shows a collection of Objects and ObservableCollection is concrete.
I've pondered a few solutions but none of them work. Seems like I will have to create one class for each object type even when they will all be the same (except for ObservableCollection having different types). That's not very DRY.
I can't make a UserControl generic, I can't let the UserControl constructor take in a generic class ( unless I define the Type wihc I don't wan't to do). I guess creating a base UserControl class and then inheriting that will have to do. Does it inherit the XAML code as well or will I have to rely on styles and templates?
Am I missing something?
Look into using DataTemplateSelector to provide flexibily in how you present your data in WPF.
Here are three sites that helped me:
Data Templating Overview
How to use DataTemplateSelector to alter views of objects in a ListBox
WPF Tutorial - How To Use A DataTemplateSelector

Resources