I’m trying to figure out best model for my WPF+MVVM+EF 6.1 application and I’m little confuse how to do this right after watching many EF courses and blogs. When modeling application in WPF there is a need for INotifyPropertyChanged, Observablecollection and also adding some additional calculated properties (not persisted on the database). I’m considering this solutions:
Change EF T4 template and implement INotifyPropertyChanged, change collections to Observablecollection and add additional fields in partial class. This brings to bind to EF model but looks simple and easer to maintain;
Use separate class for domain objects and rewrite data between them – for instance using automapper. This have separation of concerns but all updated and inserted entities have to be translated to appropriate EF entities.
Implement new class that have EF class nested inside new class with all properties wrapped and change tracked – this in other hand brings redundant code.
What will be best solution for this which not involve writing redundant code?
How about using the generated EF entities as it is and creating a DTO model that implements INotifyPropertyChanged only when it is necessary.
Not in every case you need to be able to synchronize the data between the view and the model right away.
Don't abuse the usage of INotifyPropertyChanged. It will be too late when you realize that you have a lot of extra code that doesn't actually need two way binding, a lot of repetitive work and can't be reused by other client view (could be an asp.net) because it's too technology specific (for example dependency property).
And the MVVM pattern works fine for a simple data display without you have to implement INotifyPropertyChanged for the binding data.
public class Order
{
public string OrderNo { get; set; }
public DateTime Date { get; set; }
}
public class WindowViewModel
{
public WindowViewModel()
{
var orders = Service<TheEntity>.Get();
Array.ForEach(orders, order => Orders.Add(order));
}
private readonly ObservableCollection<Order> _orders = new ObservableCollection<Order>();
public ObservableCollection<Order> Orders
{
get { return _orders; }
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new WindowViewModel();
}
}
<Window DataContext="{Binding RelativeSource={RelativeSource Self}}">
<ListView ItemsSource="{Binding Orders}">
<ListView.View>
<GridView>
<GridViewColumn Header="OrderNo" DisplayMemberBinding="{Binding OrderNo}"/>
<GridViewColumn Header="Date" DisplayMemberBinding="{Binding Date}"/>
</GridView>
</ListView.View>
</ListView>
</Window>
The best way is not to disturb auto-generated code from EF, even if you wrap it inside, new class, you still need some mechanism to track and save changes, doing it so completely overrides for what entity framework is designed for (less coding in DAL). The best way is to have properties (observable collection or i notify properties in VM- View Model). You might need to put little more code into your application but that helps you and to maintain the code and it will be total decoupled from other modules (BL, DAL, ..) of the application.
Related
I am trying to create a user control using MVVM.
Basically I am trying to wrap a combobox that will pull data from a respository. This will allow me to use the same combobox in many different views in my application. There will be many of the wrapped comboboxes throughout the application.
I was easily able to create this control using a DependencyProperty and code-behind. I am now trying to convert this to MVVM and am having trouble figuring out how to get the value back to /from the ViewModel that in bound to the View where my combobox is located.
Any ideas or suggestions would be greatly appreciated at this point.
Thanks,
Eric
It is perfectly acceptable to use a UserControl that has code behind in it when using MVVM. If you really want to move the functionality out of the UserControl, then move it to whichever parent view models will require it. If you don't want to have the same code repeated in several places, you could encapsulate it in a class and add an instance of that class as a property to each of the relevant view models.
if you have a viewmodel that will pull data from a respository - you can use the same viewmodel in many different viewmodels in your application :)
and if you use a datatemplate your views know how to render this viewmodel
<DataTemplate DataType="{x:Type local:MyPullDataViewmodel}">
<view:MyCoolPullDataShowComboboxUserControl />
</DataTemplate>
It's pretty easy.
Let's say you have:
MyUserControlView.xaml
MYUserControlViewModel.cs
MyMainWindowView.xaml - For your MainWindow view (the one containing the UserControl)
MyMainWindowViewModel.cs - Your MainWindow ViewModel.
And you want to bind List<string> MyListToBind
And leave the code-behind completely empty.
MyUserControlViewModel.cs
public class MyUserControlViewModel
{
private List<string> _MyListToBind;
public List<string> MyListToBind { get; set;}
}
MyMainWindowViewModel.cs
public class MyUserControlViewModel
{
private MyUserControlViewModel _MyControlViewModel;
public MyUserControlViewModel MyControlViewModel { get; set;}
}
MyMainWindowView.xaml
<Window ...
xmlns:my="clr-namespace:NamespaceContainingYourUserControlView>
<my:MyUserControlView DataContext = "{Binding Path= MyControlViewModel}"/>
</Window>
MyUserControlView.xaml
<UserControl ...>
<DataGrid ItemsSource = "{Binding Path= MyListToBind}" .../>
...
</DataGrid>
</UserControl>
This doesn't support ViewModel updating View. To do that You have to use either DependencyProperties as you did instead of normal variables (as i did) or use INotifyPropertyChanged(google it, you'll get tons of examples) and OnPropertyChanged event.
You might read up on DataTemplates they are really useful in data binding.
You can find this usefeul:
http://www.youtube.com/watch?v=BClf7GZR0DQ
I sure as hell did !
Good luck.
I'm on the edge of going nuts.
I have a working WinForms/database application, that I try to rebuild with WPF. My main problem is that I haven't worked with MVVM before and I can't seem to get the grip of the databinding from Entity Framework to the View.
My WinForms is build exclusively using code-behind, which I know is bad praxis, but it works.
I have read about 100 articles, tutorials and examples, downloaded a couples of demo/samples using MVVM. Including "WPF Application Framework (WAF)"
But I haven't found a simple solution/sample how to use EF as the Model or as a dataprovider for the Model. And to pass the information on to to the ViewModel, and lastly bind it from the View.
All the tutorials I have read only describe fetching data from a static list, I need the usual CRUD operations on the database.
I know questions like this are being asked all the time here, but I haven't being able to find an answer to pushing data from EF to the View(Model) and update back through EF. I hope that some of you can help a (must be retarded) person like me with some guiding.
The MVVM pattern hinges, a lot, on the INotifyPropertyChanged interface which EF implements so some of the work here is done for you.
I am not too sure on your particular requirement but start off by creating a view mode for your window. Lets assume that you have a entity called Person with an attribute of FirstName as a string and an Id of Int32 (of course), and that all the work for the data layer is taken care of. I will show you how to list the Person entity and allow edit of the person entity as well.
ViewModel
public class Window1ViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<Person> _people;
private Person _selectedPerson;
public ObservableCollection<Person> People {
get { return _people; }
set { _people = value;
this.RaisePropertyChanged("People");
}
}
public Person SelectedPerson {
get { return _selectedPerson; }
set { _selectedPerson = value;
this.RaisePropertyChanged("SelectedPerson");
}
public Window1ViewModel() {
// Instead of setting to empty collection populate with data from EF.
this.People = new ObservableCollection<Person>();
}
private void RaisePropertyChanged(string propertyName) {
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Now that you have your ViewModel taken care of it is time to create the UI and bind it.
Binding ListBox
<ListBox ItemsSource="{Binding Source={StaticResource viewModel}, Path=People}" SelectedItem="{Binding Source={StaticResource viewModel}, Path=SelectedPerson, Mode=TwoWay}"/>
Binding TextBox
<TextBox Text="{Binding Source={StaticResource viewModel}, Path=SelectedPerson.FirstName, Mode=TwoWay}"/>
Lastly you could create a button on your Window, bind it to an ICommand on your ViewModel to call the Save() method in the EF layer.
There is a lot you could write to meet your requirement i hope this goes some way to assist. Also recommend the following information. http://www.codeproject.com/Articles/81484/A-Practical-Quick-start-Tutorial-on-MVVM-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).
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.
I'm working on a project where I need to provide some treeviews to the users. So far I've managed to get my business objects and their persistence to a database fully functional.
I'm using NHibernate with SQLite3 to store the objects. The business object is as follows:
public class ErrorObject
{
public virtual int ID { get; set; }
public virtual string Description { get; set; }
private IList<ErrorObject> _errorObjects = new List<ErrorObject>();
public virtual IList<ErrorObject> ErrorObjects
{
get { return _errorObjects; }
set { _errorObjects = value; }
}
}
I'm binding this to a treeview like this:
<TreeView ItemsSource="{Binding ErrorObjects}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type DataModel:ErrorObject}"
ItemsSource="{Binding ErrorObjects}">
<TextBlock Text="{Binding Path=Description}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
What puzzles me, is the fact that, as long as I don't close the NHibernate session, I have full lazy loading out-of-the-box :o)
Can anybody advice if this is the way to continue? Or have I a flawed concept?
Seems to be a good concept.
In NET 3.5 SP1 virtualization support has been added to TreeView (by adding support for hierarchical data to VirtualizingStackPanel).
As long as NHibernate fills the child list ErrorObjects when it was requested (first access to the getter) the tree should build up with lazy loading.
That's how it's designed to work, so just be happy about it :-)
You should make the ErrorObject implement INotifyPropertyChanged/INotifyCollectionChanged if you want the UI to be updated when the collection updates, OR make the ErrorObjects property to be of type ObservableCollection<ErrorObject>, ObservableCollection<T> implements INotifyCollectionChanged and INotifyPropertyChanged`.
I think the best idea for your scenario would be use an ObservableCollection instead of the List, if I am not wrong, the ObservableCollection<T> does implement IList<T> too.