List<> Binding and button click using mvvm light - wpf

I am trying to use MVVM light to achieve something like this. I have the following scenario:
In my Model--I have set the properties like ActivityName,Image and there is a class constructor whose is accepting 2 parameters like name and image.
Im my DataAccess--I have set the database connection and implement the required method who will fetch the data from DB and I am storing in the List and returning the list to ViewModel.
In my ViewModel--I have created the list property who will return the list by calling the GetActivities() method that I have defined in the DataAccess.
Now my problem is I am not getting how to bind it in the View so that by clicking on a button it will display the list of activities with image. By clicking on some button a new window should open with the desired result. How to bind the above list and implement the button functionality using MVVM light.
Kindly help?
Thanks

First of all, use an ObservableCollection instead of a List as it would notify the view when property or collection changes.
Then set the DataContext of your view to the viewmodel. If you use MVVMLight View Class, then the DataContext would be automatically set. You've to just give the ViewModel Name there.
Then set the ItemsSource of the DataGrid like this <dg:DataGrid ItemsSource="{Binding YourListInViewModel}"/>
For handling click event you can use the Event-To-Command behaviour and write your logics in the Button's corresponding Command handler.

Bind to DataContext of the control

Related

How to bind to a method on ViewModel with data from View

I currently have one view with 3 fairly simplistic view models. For the sake of this discussion, we will focus on 2 of the three view models.
The View is a User Management user control. It contains a DataGrid that has its ItemsSource binding set to a UserListViewModel. This view model simply displays user information in the data grid.
The User Management View also contains some other controls, such as buttons for adding new users and removing users. Those buttons are currently bound to a second view model called UserManagementViewModel. For example, the Remove button will successfully call the RemoveUser method on the UserManagementViewModel.
My question is, via XAML (as I hate code-behind), how can I pass the SelectedItem property of the DataGrid (bound to UserListViewModel) into the RemoveUser method call on the UserManagementViewModel? I realize that, in the MVVM design pattern, my view model can't look into the view to retrieve the information necessary, so there must be a way via binding to pass that information into the method.
XAML code examples (or links that show how) to perform similar functionality would be appreciated. Thanks for any help!
you can simply use a commandparameter
<Button Command="{Binding RemoveCommand} CommandParameter="{Binding Elementname=gridUser, Path=SelectedItem}" />
or your UserManagementViewModel have access to the UserListViewModel then you need a command without commandparameter and simply use the SelectedUser property of your UserListViewModel instance
public void ExecuteRemove()
{
var userToRemove = this._myUserListViewModelinstance.SelectedUser;
...
}
I believe what you seek is commanding with a command target bound to the datagrid's selecteditem where one can route such information from the datagrid; say when a button is pressed.
See Commanding Overview on MSDN

Notification to View from ViewModel using MVVM Light

In my silverlight application I need to send a notification from a ViewModel to a View. In response to it a method on a UI control should be called. I know about 2 ways to accomplish this:
1) Raise an event in the ViewModel and handle it in the View's code behind.
2) Send a message from the ViewModel (using the MVVM Light messaging support) and respond to this message in the View's code behind.
I'd like to know if there is a way to accomplish this without using code in the View's code behind, for instance through some kind of data binding in the XAML?
Please share any ideas.
Additional info about what the View should do when it receives notification from ViewModel
In the XAML of the View I declare an instance of a custom Silverlight grid control which has the following method:
public void FileExportFinished(bool fileExportSucceeded)
I want to call this method from the XAML in response to the notification received from the ViewModel passing a boolean value received with the notification.
Yes...you can do it with the help of a dependency property.
Create a dependency property for that view (Make it boolean type since we just need this property to call another view method).
In its property changed call back, make provisions to call your required view method.
Then bind the DependencyProperty with a propert in ViewModel.
So when you need the view to be updated, just set the binded Property mentioned above, this will fire the property changed call back of Dependency property and form there your required view method will be called.
why not simply use a Property in your viewmodel and a DataTrigger in your xaml?
if you want some kind of dialog popup you can use a dialogservice. you should really add what you wanna do to your question. what should happen in your view when the notification arrive?
btw Messenger is for viewmodel-viewmodel communication, so thats not an option.

"Nested" MVVM Question

I have a WPF window that has a datagrid and a user control for a form for the fields in that datagrid. The user control and the WPF window have view models.
The user control's DataContext is bound to one of the window's view model's member field, whose value changes during the data grid's Selection Changed event.
I'm not sure if this is the right way to do it because I am unable to create references from the inner view model to the outer view model for some reason. Constructor injection won't work because I'm required to use default constructor only, and I can't seem to put a property injector in the right place (always getting null reference when I try to use it).
I am also unable to get my property change notification to work properly in the inner view model.
Is there a better way to wire my view models so that they automatically change the values in the user control when a new row is selected in the datagrid? I have a feeling that binding to the control's DataContext is not the way to go.
This doesn't seems a complex/nested scenario. Looks like pretty much a normal master details scenario. Suppose you want to edit Customer data, I would have an ObservableCollection instance bind to the DataGrid, and there will be a SelectedCustomer property in the VM also. In the DataGrid you can set SelectedItem twoway bind to the SelectedCustomer property which makes SelectedCustomer always updated with your selection. Since the usercontrol has the same instance of customer as in the DataGrid row, whenever you change anything in the UC those data will get reflected in the grid. Ofcourse all those properties should fire NotifypropertyChanged.

WPF MVVM UpdateSourceTrigger=Excplict

i've a contentcontrol in my Wpf-App (MVVM) which is bound to an object and displays the objects properties in textboxes, so the user can edit the values of the properties.
I want to implement undo/redo functionality with the command pattern of the GoF.
For this i need a point where i can create the command and set it into my undomanager.
My idea was to add a submitbutton. When the button is pressed, i update the sources of the textboxes (my properties) and create my command object to make the changes undoable (saving the old state of the object and the new state).
But:
- For using a submit button i need to set UpdateSourceTrigger of the textboxes to Explicit. If i want to update my sources i need to reference the controls in my view, which is bad as far as i've learned. How can i do that?
With MVVM i have to create a Command (WPF Command, not my undo redo command) for the SubmitButton but i don't see how to apply the changes to the properties from that command without referencing the textboxes (further hey are generated via datatemplates).
Thanks Walter
I assume your TextBox controls are bound to the properties in the ViewModel class. If you bind your submit button to a ViewModel Command which in turn can add appropriate command to you Command Pattern Collection and also changes some of ViewModel properties, the values in the Textbox controls will also be updated. Now, for a Textbox to update it's value when the value of a property it is bound to changes, the ViewModel class needs to implement INotifyPropertyChanged interface and raise the PropertyChanged event from the property setter with that's property's name as an argument.

How to set a value in a ViewModel from binding?

Kind of an odd question- if I'm thinking of this the wrong way please let me know. I am using an infragistics dock manager, which manages tabs as well. So I can create a TabGroupPane, and then add multiple ContentPanes, each of which has its own tab.
In each content pane, I set my viewmodel:
<ContentPane>
<viewmodels:MyViewModelForTab1 />
</ContentPane>
So here's the problem- while using a mediator pattern for communication, my viewmodels have no idea if they are on the visible tab or not, so they are always working even if hidden. The TabGroupPane does have a SelectedTab property, as well as each ContentPane having an IsActive property.
So the question is how do I set that information in my ViewModel? Making my VM a dependency object seems like a bad idea since I already implement INotifyPropertyChanged. Using a CLR prop in my VM also doesnt work, since you cannot bind to it.
How can I get my VM to know if it is the datacontext of an active tab?
Thanks!
I would put an IsSelected property on my ViewModel and bind it to the TabItem's IsSelected dependency property.
This should allow you to hook into when it is updated and perform whatever you need. You don't need a mediator pattern here since you are communicatining from the View to the ViewModel.
Make sure your ViewModel is bound to the DataContext property of the view (specifically, that the Tab's DataContext is the ViewModel). The way you have it now, your ViewModel is the content of the element, not bound to the DataContext, as it should be:
<Tab.Resources>
<viewmodels:MyViewModelForTab1 x:Key="Tab1ViewModel" />
</Tab.Resources>
<ContentPane DataContext="{StaticResource Tab1ViewModel}" />
Or something like that...
I don't know the Infragistics model, so my apologies if this is inapposite, but here's how I implement this with regular items controls - tab control, list box, whatever.
Create a container view model class that includes an observable collection of items and exposes a SelectedItem property. Make the container class the data context of the items control. Bind the items control's SelectedItem property to the container class's.
Hook the item objects up to the PropertyChanged event of the container. So now when the selected item in the UI changes, the container view model notifies all of the items that SelectedItem has changed. Each item object's event handler can determine for itself whether or not it's now the selected item.
The item objects thus don't know any implementation details of the UI - you can unit test your classes outside of a UI and the logic will still work correctly.

Resources