I have a database which is created using EF4.1 code first. The data context is as follow:
public DbSet<User> Users { get; set; }
public DbSet<Address> Addresses { get; set; }
I want to show address for a user by binding the users.Address to a datagrid in a ViewModel scenario. The problem is that I cannot convert Users.Address into a list that I can bind a collection into it. Any suggestion?
Here are some links on how to use the Local property of DbSet<> for data binding.
Using DbContext in EF 4.1 Part 7: Local Data
EF Feature CTP5: Code First Model with Master-Detail WPF Application
Related
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 do you update a WPF chart when the collection changes? I am using WPF chart (System.Windows.Controls.DataVisualization.Toolkit.dllversion version 3.5.50211.1) to plot some simple data. The classes for the data look like this:
public class EngineMeasurementCollection : Collection<EngineMeasurement>
{
}
public class EngineMeasurement
{
public int TimeStamp { get; set;}
public int Speed { get; set; }
public int Torque { get; set; }
public int Power { get; set; }
}
In my Mainform, I am receiving new data on an event callback. This comes back on another thread. I look at the data to see if it has a new TimeStamp. If it is, I add it to my collection. I then dutifully call
Dispatcher.Invoke(myDelegate, DispatcherPriority.Normal,null)
to get myself back on the GUI thread. I then call:
m_ctrlLineSeriesTorque.ItemsSource = m_TorqueCollection;
to try and get the chart to update. I've verified I get into this code. I've also verified that I can display a chart if I just throw some values into the contructor of EngineMeasurementCollection. How do I get the chart to update as I add more values to the collection?
Somewhere I saw that there might be a "Refresh" method on the chart itself. I don't see that. Also, I saw that perhaps EngineMeasurementCollection should be an "Observable collection" and EngineMeasurement should implement some interface. True?
Thanks,
Dave
Yes, your EngineMeasurmentCollection should be an ObservableCollection. Then you won't have anything more to do but add (or remove) items to the collection and the WPF binding system will take care of the rest to update the chart. That's the reason you should use an observable collection.
I have created a data grid in WPF and have 2 lists. I want to bind one column to one list and rest of the columns to another list.
Can anyone please tell me how to do this?
Thanks
Basically, You cant. The datagrid is an ItemsControl which has one ItemsSource property.
What i would do is build a view model which is a composite object that contains one of each of the items (from the two lists). then you could bind to a collection of these.
public class CompositeItem{
public Object ItemFromListOne { get; set; }
public Object ItemFromListTwo { get; set; }
}
What is the best approach to bind a WPF DataGrid ItemsSource to an ObservableCollection of ObservableCollections ?
e.g.
public ObservableCollection<ObservableCollection<MyDataItem>> DataValues = new ObservableCollection<ObservableCollection<MyDataItem>>();
where MyDataItem may look like this:
public class MyDataItem
{
public string Caption { get; set; }
public string DataValue { get; set; }
}
I can assume the collection of collections isn't jagged, and they all contain the same number of "columns"
Is it possible to bind each column dynamically to the 'DataValue' property of the MyDataItem objects or do I need to pack the data into an easier structure to bind to?
This is possible by using a collection-derived class as the inner object, and implementing ICustomTypeDescriptor on it - See a similar SO question on the topic (tagged with Silverlight, but same idea)
Silverlight DataGrid - Binding to a Collection of Collections of objects.
any help with this would be great.
I have a model
public class Master
{
...
public Detail[] Details {get; set;}
}
I am populating my view model from a WCF service which returns my collection of Master objects. I have configured the service reference to return observablecollection so I can use it easily in my view model.
My view model then has
public ObservableCollection<Master> Masters {get; set;}
public Master SelectedMaster {get; set;}
In my view I have 2 listboxes - one bound to my Masters property and the other bound to SelectedMaster.Details.
This all works fine apart from when I add try to add a new detail to the SelectedMaster.
The collection of Details in the SelectedMaster is just a list of Details (not an ObservableCollection) which is clearly why.
What options do I have here? I have tried implementing INotifyPropertyChanged but that doesn't seem to work. I could have another ObservableCollection for the Details but that means I have to keep this collection in sync when the SelectedMaster is changed (the SelectedMaster property is bound to the SelectedItem on my first listbox.
Hope this comes across OK. Would really love some feedback. Would be ideal if WCF could just return the collection of details as an observablecollection as it does with the collection of Masters but it doesn't seem to work like that.
Thanks.
I don't know enough WCF to say whether it can be configured to return nested collections as other types than simple arrays, but I'll try to give the WPF perspective.
There's no magic here, a simple array doesn't implement any kind of change notification; you simply have to wrap it in some kind of view-aware collection such as ObservableCollection.
Wrap everything up and only interact with the wrapped collections, example:
public class MasterWrapper
{
...
public MasterWrapper(Master master)
{
this.Details = new ObservableCollection<Detail>();
this.Master = master;
foreach (var detail in Master.Details)
this.Details.Add(detail);
}
...
public static ObservableCollection<MasterWrapper> GetMasters()
{
ObservableCollection<MasterWrapper> results =
new ObservableCollection<MasterWrapper>();
List<Master> modelMasters = null; // Populate this from the service.
foreach (var m in modelMasters)
results.Add(new MasterWrapper(m));
return results;
}
You're right that the issue is that the Details property does not have changes notified back to the View, because it is just an array of Detail objects...
I would make it an ObservableCollection<Detail> and load up the collection in Master's constructor, like...
public Master(Detail[] details)
{
Details = new ObservableCollection<Detail>(details);
}
remember that ObservableCollection<T> takes IEnumerable<T> or List<T> as a parameter in its constructor.