This is going to be a longish post... what I am finding is if I bind a DataForm's ItemsSource to a DomainDataSource control's Data property, the DataForm shows me all the buttons I ask for in CommandButtonsVisibility (Add, Edit, Delete, etc) In other words,
it works as expected (and just like all the demo code online)
If I take the same DomainContext (but this time in a presenter of the view) and bind the ItemsSource of a DataForm to an EntityList<TEntity> that has been loaded via the context, the Add & Delete buttons of the DataForm remain grey (disabled), but the rest
of the DataForm (edit, nav) works as expected.
To start with, here is my ultra simplitic DomainService:
[EnableClientAccess()] public class PersonService : DomainService { public IQueryable GetPerson() { return PersonHelper.GetList().AsQueryable(); }
[Insert] public void InsertPerson(Person p) { }
[Update] public void UpdatePerson(Person p) { }
[Delete] public void DeletePerson(Person p) { } }
Here is the XAML of a page using the DomainDataService control. This WORKS AS EXPECTED (i.e. Navigation works, edit works, add works, delete works, commit works, cancel works)
Here's the other approach, using a presenter and a Domain Context. Firstly, the codebehind / presenter (very simplistic implementation):
public partial class Home : Page { public Home() { InitializeComponent(); DataContext = new HomePresenter(); }
// Executes when the user navigates to this page. protected override void OnNavigatedTo(NavigationEventArgs e) { } }
public class HomePresenter : INotifyPropertyChanged { public PersonContext PersonContext { get; set; } public HomePresenter() { PersonContext = new PersonContext(); PersonContext.Load(PersonContext.GetPersonQuery(), PersonsLoadedCallback, null); }
The second attempt displays the list of items in the DataForm and allows navigation, edit, commit, cancel. The Add & Delete buttons, however, remain disabled.
This has been frustrating me all day, because the two techniques should surely yield the same results. In the second case, PersonContext.Persons is of type EntityList<Person> and the properties CanAdd, CanEdit, CanDelete are all true.
Is this a BUG?! am i missing something? i like the idea of the DomainDataSource, but the app I am building uses MVP and data binding. We'd be breaking our pattern to make data access purely declarative
After a bit more experimentation, I tried creating a DomainDataSource in the Presenter, like this:
public partial class Home : Page
{
public Home()
{
InitializeComponent();
DataContext = new HomePresenter();
}
// Executes when the user navigates to this page.protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
}
public class HomePresenter : INotifyPropertyChanged
{
public DomainDataSource PersonDDS { get; set; }
public HomePresenter()
{
PersonDDS = new DomainDataSource();
PersonDDS.DomainContext = new PersonContext();
PersonDDS.QueryName = "GetPersonQuery";
PersonDDS.Load();
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyChange(string property)
{
if (PropertyChanged == null) return;
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
Now - interestingly - this works as expected. the collection is bound to the dataform and all buttons are visible and work correctly.
Is it good practice to use a DomainDataSource in the codebehind / presenter ? it certainly seems less flexible than using an instance of the DomainContext... interested to get some perspectives here
To simplify things even further (remove the Presenter):
Codebehind:
public partial class Test : Page { public Test() { InitializeComponent(); var ctxt = new PersonContext(); dataform1.ItemsSource = ctxt.Persons; ctxt.Load(ctxt.GetPersonQuery()); }
// Executes when the user navigates to this page. protected override void OnNavigatedTo(NavigationEventArgs e) { }
I'm not sure if dataform support add delete operation on DomainSource directly. dataform manipulate datasource as a IEnumable collection, but domainsource need a excute a group of operation to confirm the modification on entities.
DomainDataSource like an adapter to cooperate with datapresenter (dataform/datagrid) and datasource (DomainSource).
Tom - The reason the DataForm won't bind directly to Persons is that the DataForm uses a ICollectionView\IEditableCollectionView internally which looks at the interfaces the object\collection you are binding to implements. If the object\collection implements
IList and their is a parameter-less constructor for the type in the collection then Add's will be allowed. The issue is that EntityList doesn't support IList. As mentioned before you could use DDS. If you didn't want to use DDS you could do something similar
to what DDS does, basically add the items returned from the query into an IList and then when Add\Removes are done on that list you can call the subsequent Add\Remove on EntityList. You would then pass the IList to DataForm and then it would work as you expect.
tadam
-- Please mark the post as answered if I've answered you question.
There is another thread discussing some of these issues. The problem is that the collection that backs the DDS, EntityCollectionView, is internal to RIA Services. Jeff Handley is talking
about create a version of EntityCollectionView which we can use directly and that will make it much easier to implement binding between the DataForm and {ViewModel, Presenter, TheBindeyThing}s.
You'll notice that I'm using the name EntityCollectionView for the solution, but please don't confuse this with the EntityCollectionView that Colin mentioned. During a meeting today, we realized that EntityCollectionView is really poorly named for the DomainDataSource,
and that name should really be used for something like what my blog post provides. I knew there was a good reason the DDS EntityCollectionView eas internal. :-)
Note: the solution I provided is only tested for blog quality - it works on my machine in the simple cases I've tested. I'd love to hear how it works for you.
There is an internal class inside WCF RIA Services named EntityCollectionView. It is used by the DDS to do the paging. At one point there was talk about making it public, instead they created the public DomainDataSourceView which interacts with the DDS and
the EntityCollectionView.
As a separate issue, there needs to be a public EntityCollectionView as well. If Jeff is successful getting the
source code of RIA Services shipped then I am planning to release one as part of RIA Services Contrib.
TomBeeby
Participant
1161 Points
188 Posts
Add new entity via DataForm buttons
Jul 16, 2009 07:08 AM | LINK
This is going to be a longish post... what I am finding is if I bind a DataForm's ItemsSource to a DomainDataSource control's Data property, the DataForm shows me all the buttons I ask for in CommandButtonsVisibility (Add, Edit, Delete, etc) In other words, it works as expected (and just like all the demo code online)
If I take the same DomainContext (but this time in a presenter of the view) and bind the ItemsSource of a DataForm to an EntityList<TEntity> that has been loaded via the context, the Add & Delete buttons of the DataForm remain grey (disabled), but the rest of the DataForm (edit, nav) works as expected.
To start with, here is my ultra simplitic DomainService:
Here is the XAML of a page using the DomainDataService control. This WORKS AS EXPECTED (i.e. Navigation works, edit works, add works, delete works, commit works, cancel works)
Here's the other approach, using a presenter and a Domain Context. Firstly, the codebehind / presenter (very simplistic implementation):
And here's the XAML:
The second attempt displays the list of items in the DataForm and allows navigation, edit, commit, cancel. The Add & Delete buttons, however, remain disabled.
This has been frustrating me all day, because the two techniques should surely yield the same results. In the second case, PersonContext.Persons is of type EntityList<Person> and the properties CanAdd, CanEdit, CanDelete are all true.
Is this a BUG?! am i missing something? i like the idea of the DomainDataSource, but the app I am building uses MVP and data binding. We'd be breaking our pattern to make data access purely declarative
Tom
http://blog.tombeeby.com
TomBeeby
Participant
1161 Points
188 Posts
Re: Add new entity via DataForm buttons
Jul 16, 2009 07:31 AM | LINK
After a bit more experimentation, I tried creating a DomainDataSource in the Presenter, like this:
And made the the XAML look like this:
Now - interestingly - this works as expected. the collection is bound to the dataform and all buttons are visible and work correctly.
Is it good practice to use a DomainDataSource in the codebehind / presenter ? it certainly seems less flexible than using an instance of the DomainContext... interested to get some perspectives here
Tom
http://blog.tombeeby.com
TomBeeby
Participant
1161 Points
188 Posts
Re: Add new entity via DataForm buttons
Jul 16, 2009 08:22 AM | LINK
To simplify things even further (remove the Presenter):
Codebehind:
XAML:
Again, navigation and edit works, Add & Delete are disabled.
This can't be the way it is supposed to work!
Tom
http://blog.tombeeby.com
Maud
Contributor
3551 Points
483 Posts
Re: Add new entity via DataForm buttons
Jul 22, 2009 11:16 AM | LINK
Hi,
I'm not sure if dataform support add delete operation on DomainSource directly. dataform manipulate datasource as a IEnumable collection, but domainsource need a excute a group of operation to confirm the modification on entities.
DomainDataSource like an adapter to cooperate with datapresenter (dataform/datagrid) and datasource (DomainSource).
That's what I think.
tadam
Member
178 Points
36 Posts
Re: Re: Add new entity via DataForm buttons
Jul 22, 2009 06:20 PM | LINK
Tom - The reason the DataForm won't bind directly to Persons is that the DataForm uses a ICollectionView\IEditableCollectionView internally which looks at the interfaces the object\collection you are binding to implements. If the object\collection implements IList and their is a parameter-less constructor for the type in the collection then Add's will be allowed. The issue is that EntityList doesn't support IList. As mentioned before you could use DDS. If you didn't want to use DDS you could do something similar to what DDS does, basically add the items returned from the query into an IList and then when Add\Removes are done on that list you can call the subsequent Add\Remove on EntityList. You would then pass the IList to DataForm and then it would work as you expect.
-- Please mark the post as answered if I've answered you question.
ColinBlair
All-Star
28559 Points
4828 Posts
Re: Re: Add new entity via DataForm buttons
Jul 22, 2009 07:02 PM | LINK
There is another thread discussing some of these issues. The problem is that the collection that backs the DDS, EntityCollectionView, is internal to RIA Services. Jeff Handley is talking about create a version of EntityCollectionView which we can use directly and that will make it much easier to implement binding between the DataForm and {ViewModel, Presenter, TheBindeyThing}s.
http://www.RiaServicesBlog.net
ColinBlair on Twitter
MVVM and RIA Services
JeffHandley
Participant
764 Points
146 Posts
Microsoft
Re: Re: Add new entity via DataForm buttons
Aug 14, 2009 09:57 AM | LINK
I've put together a way to get around this problem of binding the DataForm directly to the EntityList. I blogged about it here:
http://jeffhandley.com/archive/2009/08/14/entitycollectionviewconverter.aspx
You'll notice that I'm using the name EntityCollectionView for the solution, but please don't confuse this with the EntityCollectionView that Colin mentioned. During a meeting today, we realized that EntityCollectionView is really poorly named for the DomainDataSource, and that name should really be used for something like what my blog post provides. I knew there was a good reason the DDS EntityCollectionView eas internal. :-)
Note: the solution I provided is only tested for blog quality - it works on my machine in the simple cases I've tested. I'd love to hear how it works for you.
Thanks,
Jeff Handley
DataForm EntityList
bobg2009
Member
82 Points
184 Posts
Re: Re: Add new entity via DataForm buttons
Jan 25, 2010 12:31 AM | LINK
Hi Jeff,
I am unable to get your code to work with the November release of WCF Ria Services.
Are you able to assist?
cheers.
Casimodo72
Participant
1042 Points
458 Posts
Re: Re: Add new entity via DataForm buttons
Jan 25, 2010 03:37 AM | LINK
A DDS is an EntityCollectionView - interesting.
Can anyone elaborate on this?
Regards,
Kasimier
ColinBlair
All-Star
28559 Points
4828 Posts
Re: Re: Add new entity via DataForm buttons
Jan 25, 2010 03:34 PM | LINK
There is an internal class inside WCF RIA Services named EntityCollectionView. It is used by the DDS to do the paging. At one point there was talk about making it public, instead they created the public DomainDataSourceView which interacts with the DDS and the EntityCollectionView.
As a separate issue, there needs to be a public EntityCollectionView as well. If Jeff is successful getting the source code of RIA Services shipped then I am planning to release one as part of RIA Services Contrib.
http://www.RiaServicesBlog.net
ColinBlair on Twitter
MVVM and RIA Services