How to update the UI using bindings - wpf

I have a DataGrid and two ListBoxes in my window. I am using Entity Framework to Connect to my SQL Server. Depending on the selections I make in the ListBoxes parameters will be passed to my stored procedure and data for my DataGrid will be retrieved. I was able to implement this functionality without using MVVM. I would like to know ways to implement this using MVVM. Please Help me out. Thanks in Advance.

First of all, MVVM is about separating the concerns of your code into the appropriate area. For example, talking to your database via EF should be done in the Model1. The ViewModel is responsible for holding the data, and for shaping or massaging it to make it more suitable for display (i.e. transforming enums to colors2, etc).
To implement your functionality in a MVVM way, you will need to use binding, and bind your viewmodel to your view:
<MyControl>
<LayoutRoot>
<ListBox ItemsSource={Binding MyItems} SelectedItem={Binding MySelection} />
</LayoutRoot>
</MyControl>
in the code behind for the View:
public class MyControl
{
public MyControl()
{
this.DataContext = new MyViewModel();
}
}
and your ViewModel will look something like this:
public class MyViewModel : INotifyPropertyChanged
{
public ObservableCollection<MyDataObject> MyItems
{
get { return _myItems; }
set
{
_myItems = value;
OnPropertyChanged("MyItems");
}
}
public MyDataObject MySelection { get; set; }
public void DoSomethingWithDatabase()
{
Model.DoSomething(MySelection);
}
}
This is just a VERY simple example to illustrate what is required if you do things the MVVM way (and I've deliberately missed out a bunch of stuff). To do a proper example and document all the essential bits you need to know would take at least a chapter in a book, so I'll refer you to a MSDN article for further reading: Implementing the Model-View-ViewModel Pattern.
1 And the Model may just be a stepping stone if you also implement SOA, the Model might just call a service which then talks to the database.
2 This can also be done with Converters in the View, but may not always be possible or practical in a converter.

Related

Using WPF design data with the MVVM pattern

I'm using the MVVM pattern in our WPF application to allow for comprehensive unit testing. The MVVM pattern itself is working great, however I'm struggling to adapt the pattern in a way that means I can use the design-time data support of WPF.
As I'm using Prism the ViewModel instances are generally injected into the constructor of the view, like so
public MyView(MyViewModel viewModel)
{
DataContext = viewModel;
}
Dependencies for the ViewModel are then injected into the constructor, like so
public class MyViewModel
{
public MyViewModel(IFoo foo, IBar bar)
{
// ...
}
// Gets and sets the model represented in the view
public MyModel { get; set; }
// Read-only properties that the view data binds to
public ICollectionView Rows { get; }
public string Title { get; }
// Read-write properties are databound to the UI and are used to control logic
public string Filter { get; set; }
}
This is generally working really well except when it comes to design data - I wanted to avoid compiling design-data specific classes into my released assembly and so I opted to use the {d:DesignData} approach instead of the {d:DesignInstance} approach, however in order for this to work correctly my ViewModel now needs to have a parameterless constructor. In addition, I also often need to change additional properties either to have setters or to be modifiable collections in order to be able to set these properties in XAML.
public class MyViewModel
{
public MyViewModel()
{
}
public MyViewModel(IFoo foo, IBar bar)
{
// ...
}
// Gets and sets the model represented in the view
public MyModel { get; set; }
// My read-only properties are no longer read-only
public ObservableCollection<Something> Rows { get; }
public string Title { get; set; }
public string Filter { get; set; }
}
This is worrying me:
I have a parameterless constructor that is never intended to be called and isn't unit tested
There are setters for properties that only the ViewModel itself should be calling
My ViewModel is now a jumbled mixture of properties that should be modified by the view, and those that shouldn't - this makes it tricky to tell at a glance which piece of code is responsible for maintaining any given property
Setting certain properties at design time (e.g. to see styling on the Filter text) can actually end up invoking ViewModel logic! (so my ViewModel also needs to be tollerant of otherwise mandatory dependencies being missing at design time)
Is there a better way to get design-time data in a WPF MVVM application in a way that doesn't compromise my ViewModel in this way?
Alternatively should I be building my ViewModel differently so that it has more simple properties with the logic separated out somewhere else.
First, I would recommend you to have a look at this video where Brian Lagunas provides several best practices about MVVM. Brian is - at least - involved in the development of Prism, as his name appears in the nuget packages information. Didn't check further.
On my side I only use bits of Prism, and my Model and ViewModel always offer blank constructors (like what Brian shows), the data context is assigned in the view's XAML, and I set the properties values like :
<MyView.DataContext>
<MyViewModel />
</MyView.DataContext>
and
public void BringSomethingNew()
{
var myView = new View();
(myView.DataContext as ViewModel).Model = myModel;
UseMyView();
}
Another benefit with this approach is that the ViewModel is created once, with the same path at design and run time, so you create less objects and save GC efforts. I find this elegant.
With regards to the setters, the design data will still work if you make them private, like:
public string MyProp { get; private set; }
Ok, customize it to manage NotifyPropertyChange at your convenience, but you've got the idea.
Now, I don't have yet a solution to manage ObesrvableCollections (I face the same problem, although putting multiple values in XAML sometimes work... ???), and yes, I agree that you have to manage the case when the properties are not set, like setting default values in the constructor.
I hope this helps.
I too have worked with NUnit testing with WPF and MVVM implementation. However, my version is reversed from yours. You are creating the view first, then creating the model to control it.
In my version, I create the MVVM model FIRST and can unit test it till the cows come home and not worry about any visual design... if the model is broken, so too will the visual implementation.
in my MVVM model, I have a method to "GetTheViewWindow". So, when I derive from my MVVM baseline, each view model has its own view its responsible for. So via a virtual method, each instance will do its own new view window when being applied for production.
public class MyMVVMBase
{
private MyViewBaseline currentView;
public MyMVVMBase()
{ // no parameters required }
public virtual void GetTheViewWindow()
{ throw new exception( "You need to define the window to get"; ) }
}
public class MyXYZInstanceModel : MyMVVMBase
{
public override void GetTheViewWindow()
{
currentView = new YourActualViewWindow();
}
}
Hope this helps as an alternative to what you are running into.

How should I populate the ViewModel in WPF?

I'm new to WPF and I'm writing a simple test app to familiarize myself with it. My test app will detect all joysticks I have attached to my computer and display information about it. So far, I have this ViewModel:
public class JoystickViewModel
{
public ObservableCollection<Joystick> Joysticks { get; set; }
public JoystickViewModel()
{
GetAttachedJoysticks();
}
private void GetAttachedJoysticks()
{
// populate Joysticks collection by using SlimDX
}
}
And this is my codebehind for my MainWindow.xaml:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new JoystickViewModel();
}
}
And my XAML for MainWindow:
<Window ...>
<Grid>
<ComboBox ItemsSource="{Binding Joysticks}"
DisplayMemberPath="Information.ProductName"/>
</Grid>
</Window>
I followed a tutorial that also populated the ViewModel in its constructor.
My question is, how should I populate the ViewModel? It seems sort of weird to me that I'm population the collection in the ViewModel constructor. Should this logic be in MainWindow's codebehind instead? Or somewhere else altogether? The end goal is to not only have this collection populated, but also updated periodically to reflect the current state (user plugged in new joystick, unplugged existing one, etc...).
The MainWindow code behind is definitively not the place where "business" logic should occur, as the View should be kept as simple as possible.
Keep your fetch/update logic inside of your viewmodel, this way you can test it easily and independently.
From a learning perspective, it's important to keep concerns separated :
the View is bound to the ViewModel, and has no intelligence
the ViewModel has knowledge on how to get the Model
the Model represents the data
In your case, the VM knowledge is at the moment a call inside it's constructor. Later you can change this to call some IJoystickDataService interface, and wire everything using a MVVM framework.
I would have your JoySticks observable collection property (and the code that populates it) in a Model class. The viewmodel simply exposes this same property to the view for binding. The vm should be as thin as possible - ideally just exposing properties that are in the model for binding and not doing any kind of 'business' logic (i.e. populating joystick info as in your case).

WPF DataTemplate / DataTemplateSelector -- Best approach for a ViewModel used by 2 different Views?

Basically, I have the following scenario:
ViewModel: FooViewModel : BaseViewModel, BarViewModel : BaseViewModel
Views: MainView, FooView, BarView
Right now I "inject" the view and set the DataContext using DataTemplate and DataTemplateSelector. Obviously, my ItemsControl ItemSource is bound to an ObservableCollection<BaseViewModel> in which it contains (for now) an instance of a FooViewModel and a BarViewModel
The problem is I want to introduce a AlternateFooView which I want to utilize the same FooViewModel. I figure I'll create another DataTemplate and have my DataTemplateSelector return it, but there needs to be special logic to determine which DataTemplate to return (I can't just go by which ViewModel is there), and that means I'll have to have some type of property or field in the BaseViewModel. I don't know if that's really a good idea because that seems to be introducing a field/property into the ViewModel that is only used to select a view. It won't hurt my unit testing, but it seems like a waste to include a field just to help decide which UI View to choose. I don't think it breaks MVVM, but I'm curious if anyone out there has any other better ideas? The alternative ideas I had I dislike even more...
Idea #2:
- Turn FooViewModel into a base class that 2 different FooViewModel's extend (i.e. BaseFooViewModel, FooViewModel, DifferentFooViewModel). This seems stupid because there really isn't any difference between FooViewModel and DifferentFooViewModel aside from their class type.
Idea #3:
- Just copy FooViewModel and make it FooViewModel2 (it'll be exactly identical to FooViewModel). This seems even worse than idea #2.
Sample-Code (Adjusted obviously):
public abstract class BaseViewModel : NotificationObject
{
//Common Stuff
}
public abstract MainViewModel : NotificationObject
{
public MainViewModel()
{
MyItems = new ObservableCollection<BaseViewModel>()
{
new FooViewModel();
new BarViewModel();
new FooViewModel(); //New Item -- I want it to use the DifferentFooView
}
//Load items from a DAL later
}
public ObservableCollection<BaseViewModel> MyItems { get; set; }
//Other Stuff
}
<l:MyItemsControl ItemSource={Binding MyItems} ContentTemplateSelector={StaticResource MyTemplateSelector} />
Thanks!
I agree with krishnaaditya that the question really boils down to what determines which View to use based on the state of the ViewModel. This type of logic is often placed into a template selector, which works great. If you don't want to put that logic into the template selector, consider externalizing it by using my Routed Template Selection approach. That makes it easy to delegate the template selection logic by using a routed event.
The idea you proposed in your comment about using a DataTrigger could also work, but that reintroduces the need for a property on the VM object that indicates which View to load (which you said you don't want). In my opinion, that's not necessarily a bad thing.

WPF MVVM Dilemma: ViewModel as Control-derivate with Style or as POCO with UserControl?

I am currently working on a new project of mine that is going to be a data record visualizer (for records in Pascal). It should provide a way to define a given record with data fields and pointer fields and then there will be an example view where you can see the record "in action".
Now the problem I am having is that in this model there are records and components and the relationship between them is that one record has multiple components (data and pointer as mentioned above).
I want to use MVVM for the app but I am now unsure how I should approach this. I modelled the record and components into RecordViewModel and ComponentViewModel (with derivates DataComponentVM, PointerComponentVM).
Now to provide a look for these VMs there are 2 options as far as I know:
Deriving the ViewModels from Control and providing a ControlTemplate
Creating a UserControl using the ViewModel as DataContext
The UserControl approach works fine for the RecordViewModel but when I try to design the way the ComponentViewModels are shown (in a ContentPresenter) this approach fails because I would need to provide a collection of UserControls (instead of DataComponentViewModels) in my RecordViewModel that would make that work (and I am pretty sure that is not a good idea).
The Control approach also has the problem that the ViewModels aren't POCOs anymore which I think has a strange feel to it and is also not considered good practice.
Is there any other way to solve the problem? Do you have any other good advice for me in this regard?
Thanks in advance!
Code:
public class RecordViewModel : BaseViewModel
{
public RecordViewModel()
{
Components = new ObservableCollection<ComponentViewModel>();
}
public ObservableCollection<ComponentViewModel> Components { get; set; }
}
public class DataComponentViewModel : ComponentViewModel
{
public string Type { get; set; }
}
public class PointerComponentViewModel : ComponentViewModel
{
public object Target { get; set; }
}
Oh god why didn't I think of this before?
I was only thinking about ControlTemplates (therefore needing my ViewModels to derive from Control) when there are also DataTemplates that work exactly like I wanted them to.
I got lost as to why you think you need to provide a collection of user controls, but it sounds like what you really want is for the RecordViewModel to have some variation of:
ObservableCollection<ComponentViewModel> Components
Components is then bound in xaml to the ItemsSource property of some sort of ItemsControl. Whether or not the ComponentViewModel needs it's own UserControl depends on what you are trying to do with it.
If that doesn't start to click for you then you may want to post some code so we can sort it out.

Should I use DTOs as my data models in MVVM?

I'm currently working on what will be my first real foray into using MVVM and have been reading various articles on how best to implement it.
My current thoughts are to use my data models effectively as data transfer objects, make them serializable and have them exist on both the client and server sides.
It seems like a logical step given that both object types are really just collections of property getters and setters and another layer in between seems like complete overkill.
Obviously there would be issues with INotifyPropertyChanged not working correctly on the server side as there is no ViewModel to which to communicate, but as long as we are careful about constructing our proper domain model objects from data models in the service layer and not dealing the the data models on the server side I don't think it should be a big issue.
I haven't found too much info about this approach in my reading, so I would like to know if this is a pretty standard thing, is this just assumed to be the de facto way of doing MVVM in a multi-tier environment?
If I've got completely the wrong idea about things then thoughts on other approaches would be appreciated too.
You can use whatever model you feel comfortable with, yes all of your properties will need INotifyPropertyChanged behavior. How this will effect the service layer is entirely down to your implementation.
I'm assuming that you ment that you bind to your DTO's in your view?
How I see it is that there is an impedence mismatch between the layers of the application, that is your
Domain Model probably looks simliar to your Relational Model, with subtle but crucial differences. There is also
a mismatch between the Domain Model and your DTO's (objects may be flattened, computed properties, etc, ...). It's tempting to bind directly to the DTO's as they are probably designed to have what you need for the particular operation, however there is also an impedence mismatch between the DTO and what is needed by the view in order to acheive the desiged outcome. This is where the View Model comes in. The view model has responsibility to proxying the DTO properties to the view, it is responsible for letting the view know if there are validation errors, and routes commands to the appropriate handler (Save, Delete, etc, ...).
I tend to set things up in the following way :
// POCO object. Serializable.
public class AddressDto
{
public int Id { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string Country { get; set; }
}
// IDataErrorInfo for validation.
public class AddressViewModel : INotifyPropertyChanged, IDataErrorInfo
{
private readonly AddressDto addressDto;
public AddressViewModel(AddressDto addressDto)
{
this.addressDto = addressDto;
}
public int Id { /* get and set for property changed event and update dto */ }
public string Street { /* get and set for property changed event and update dto */ }
public string City { /* get and set for property changed event and update dto */ }
public string Country { /* get and set for property changed event and update dto */ }
...
// IDataErrorInfo implementation
}
public class EditAddressViewModel : INotifyPropertyChanged
{
public AddressViewModel Address { /* get and set for property changed event */ }
public ICommand Save { /* setup command */ }
public ICommand Cancel { /* setup command */ }
private void Save()
{
}
private void Cancel()
{
}
}
Your EditAddressView would then bind to the EditAddressViewModel. Basically the rule is all of your UI behavior should be expressed in terms of your view model.
Yes that does mean extra work, howerver there are things you can do to simplify things a bit (code generation etc). I'm actually working on a library that aims to simplify whole MVVM process using a fluent api. Check it out at http://fluentviewmodel.codeplex.com/
I'm no expert on this. I had just the same scenario. I agree with you that that is quite an overkill. I've been using this solution for quite some time now and haven't encountered any issues. The INotifyPropertyChanged isn't a big problem for me since nothing on the server-side will subscribe to the PropertyChanged event. If you will use inheritance on your data models, then all must be serializable. In my scenario, I have two base classes for my data models: one that is used for data transfer, and the other not.
I decided to have a property "Model" on my ViewModel. In the model itself I already implement IPropertyNotifyChanged and IDataErrorInfo. In my ViewModel I thus skip properties where the code would simply "fall-through" to the model. Instead, the View binds directly to the model for those properties.
For more complicated cases, where I have to adjust the data in the model to fit the view, I do this in the ViewModel. Also, the commands, etc. are in the ViewModel. But I do not see the reason to have boilerplate code in the ViewModel repeating the same stuff which I already have in the model.

Resources