I have a question which seems too specific for google, or maybe I don't use the correct words; I find nothing about this.
I have severals tables and each of them contain several Entities (columns). Every tables has a Common Primary Key, we can use this column as a link for every table.
I want to pick some entities of a table, other entities of another table, other entities of another table, etc.. and send'em to a unique ObservableCollection, this ObservableCollection will be, in a second step, binded to a DataGrid.
I could create an ObservableCollection per table and then create a CompositeCollection of each ObservableCollection but I don't want to use the CompositeCollection, It doesn't display Datas as I want, I discovered this here(CompositeCollection binding on a DataGrid by MVVM)
How can I perform this? I have found lot of scripts but nothing about sending specific columns from specific tables on a unique ObservableCollection.
I hope I have been clear enough, If you want some code to illustrate, I can send what you want. But as it's a general question of a specific way to add datas on an ObservableCollection, I think it isn't necessary.
Thanks in advance!
EDIT1:
This is what my Database looks like:
(http://imagik.fr/view/123053)
Related
I'm working with the WPF DataGrid and .Net 4.5 and I'm trying to roll my own data virtualization container for a large collection. I've been all over the web and found many helpful examples of how to implement data virtualization, but in every example I've seen, the savings are lost if you do any grouping. My grouping is simple and static. Is there a way to fake grouping in WPF in such a way that my collection doesn't have to enumerate all items ahead of time? For example, has anyone ever overridden the ListCollectionView's GetItemAt() and just returned a CollectionViewGroup object at the start of each group?
Concrete Example:
Say for example I have a database with 100K records. I want to create a data virtualization collection similar to Bea Stollnitz' example and use it in a WPF DataGrid.
I want to group items in the DataGrid on a field, but I can do that by modifying my database query to first return all items in group A, then all items of group B. Grouping is done before the DataTable even sees it.
How do I visually represent the grouping inside the WPF DataGrid even though my collection (from the DataGrid's perspective) is flat? The only way I've found to show grouping in a DataGrid is by using a CollectionView or similar.
.
If you are dealing with a flat list and a static grouped list and are worried about performance related to the aggregation, I would consider storing both versions of the data sets in an index and just grab whichever one you need for each particular case.
I have created a databinding treeview which binds with multiple tables and display hierarchical data. I stole much of the mechanism from http://www.codeproject.com/KB/tree/dbTree.aspx if it interests you.
I first merge(outer join) all the datatables into a big datatable, then databind the treeview and bunch of textboxes to the big table. User can click on a node in the treeview and see corresponding info in the textboxes. So viewing part is nice.
Now coming to updating, deleting, adding info via textboxes entries, is there a way the user can make changes via the textboxes, and immediately reflected in the big table and individual tables ?
Thanks!!
You are joining information in a kind of view and I understand that this view is stored in memory while you fill your tree. So, if you do any kind of change in the data inside the tables that composes your view, you must reload it.
If you are working with an web app, it is going to be something natural, because each user interaction will do a new request to create you view.
I have a grid (DevExpress XtraGrid, if that matters) which is bound to a LINQ to SQL Entity property.
gridItems.DataSource = purchaseOrder.PendingItemsGrouped;
Well, the grid is being displayed properly,and I can see the purchase items that are pending.
The problem arises when purchaseOrder.PendingItemsGrouped gets changed ... once that happens, the grid does not reflect the changes.
The exact procedure is as following:
The user selects a row from the grid, inserts a serial number on a specific textbox, and then hits enter effectively receiving this item from the purchase order, and inserting it into stock.
inventoryWorker.AddItemToStock( userSelectedItem, serialNumber );
The item gets properly inserted to the inventory, but the grid still shows the item as if it is still awaiting it to be received.
How do I solve this problem?
Do I really need to re-bind the grid so the changes can be reflected?
I even tried instead of:
gridItems.DataSource = ...;
This:
gridItems.DataBindings.Add( new Binding( "DataSource", purchase, "PendingItemsGrouped" ) );
But couldn't solve the problem.
Thank you very much for your time,
Isaac.
OBS:
Re-Binding the Grid works, but my question is ... is that even the proper way of doing things? I feel like I'm miles off the right track.
Calling databind is actually the right approach when you think about how databinding in webforms works. In all examples when databinding to objects, calls to databind happen whenever the collection is modified.
The reason it feels wrong is because its a lot cleaner to use a DataSourceControl, such as a LinqDataSourceControl or ObjectDataSourceControl, where all that stuff is handled for you.
Two things that might help you along this path is when using a LinqDataSourceControl, you might need to override the various -ing methods (Selecting, Inserting, Deleting) etc, in order to add additional filtering and logic.
The other thing that springs to mind is http://multitierlinqtosql.codeplex.com/. Especially the section on Custom ObjectDataSource.
I have not tried it myself but Bindable LINQ allows to achieve it.
I am experiencing with a class generator I've written, which generates a class for each table in database with each table field as a property and such.
Before that, I used to add a typed dataset to the project and add some tables to it. It automatically detected the relationship between tables and when I added a parent table as data source of a datagrid, I could add another datagrid and use the foreing key data member of it's bindingsource to fill it, and when someone moved the focus on parent datagrid, the data in child datagrid would change accordingly.
Now that I have my classes, I add an object as data source for my 2 datagrids, but obviously it doesn't detect a parent child relation. But It'd really help if I could have that foreign key relation in my object datasources.
Is there any way to have that relation in object datasource?
If you use LINQ ORM, your foreign key relationships are reflected automatically in your generated model.
Take a look at http://www.hookedonlinq.com/LINQtoSQL5MinuteOverview.ashx for more info.
In case you use ADO.Net, there might be a chance you forgot to tick the choice "Include Foreign Key Columns in the Model." in the ADO wizard but no worries (we've all been there, tick boxes are notoriously easy to overlook ;) ), you'll simply have to re-generate the model (re-run the wizard) but be sure to copy-paste any custom code you've added to a text file or something, so you don't lose it. Good luck!
I'm developing a WinForms application (.Net 3.5, no WPF) where I want to be able to display foreign key lookups in a databound DataGridView.
An example of the sort of relationship is that I have a table of OrderLines. Orderlines have a foreign key relationship to Products and Products in turn have a foreign key relationship to ProductTypes.
I'd like to have a databound DataGridView where each row represents an orderline, displaying the line's product and producttype.
Users can add or edit orderlines direct to the grid and choose the product for the order line from a comboBoxColumn - this should then update the producttype column, showing the producttype for the selected product, in the same row.
The closest to a good fit that I've found so far is to introduce a domain object representing an orderline then bind the DataGridView to a collection of these orderlines. I then add properties to the orderline object that expose the product and the producttype, and raise relevant notifypropertychanged events to keep everything up to date. In my orderline repository I can then wire up the mappings between this orderline object and the three tables in my database.
This works for the databinding side of things, but having to hand code all that OR-mapping in the repository seems bad. I thought nHibernate would be able to help with this wiring up but am struggling with the mappings through all the foreign keys - they seem to work ok (the foreignkey lookup for an orderline's product creates the correct product object based on the foreign key) until I try to do the databinding, I can't get the databound id columns to update my product or producttype objects.
Is my general approach even in the right ballpark? If it is, what is a good solution to the mapping problem?
Or, is there a better solution to databinding rows including foreign key lookups that I haven't even considered?
I think the problem you're having is that when you are binding to a grid, it is not enough to support INotifyPropertyChanged, but you have to fire the ListChanged events in your IBindingList implementation and make sure that you override and return true for the SupportsChangeNotification property. If you don't return true for this, the grid won't look for it to know if the data has changed.
In .NET 2.0+, you can create a generic collection using the BindingList class, this will take care of most of the nastiness (just don't forget to override and return true for the SupportsChangeNotification property).
If the class you use for data binding has a property that is a collection (such as IBindingList or BindingList), then you can bind the foreign key grid to that property directly. When you configure the bindings in the Forms designer, just select the collection property as the data source for the grid. It should "just work". The only sneaky part is making sure that you handle empty or null collections the right way.
welcome to StackOverflow :)
Normally what you would do is base the information in the drop down on two values ValueMember and DisplayMember.
The ValueMember is the source of the actual controls value (this will be the key value in the order line), the display member is the value that is displayed to the user instead of the value (this will be the FK value).
Is there no particular reason you cannot just return all the data required and set these properties?
Here's a good "How Do I" video that demonstrates data binding:
http://windowsclient.net/learn/video.aspx?v=52579
Well, I don't know whether it's supported by the DataGridView, but when you're doing regular WinForms databinding (say, to a regular TextBox) you can use property paths to navigate through object relationships.
Something like this:
myTextBox.DataBindings.Add("Text", anOrderLine, "OrderedPart.PartNumber");
Would be worth seeing if this works in your situation too.
My original question obviously wasn't clear, sorry about that.
The problem wasn't with databinding to a DataGridView in general, or with the implementation of a DataGridViewComboBoxColumn - as the people who have answered already rightly say, that is well documented on the web.
The problem I've been trying to solve is with the refresh of properties that are drilling down through relationships.
In my orders example, when I change the value of the "Product" column, the "Product Type" column is not being updated - even though in the code I am setting the property and firing the NotifyPropertyChanged event. (In debug I go to all the right places)
After a lot of poking around I realised that this was not even working when I directly set the "Product Type" property of datasource, rather that setting it in the "Product" setter.
The other thing that I believe has me back on the right track is that when I provide a mocked dataccess layer, created in the main form, everything works fine.
Also, when I copy the IList made by nHibernate to a IBindingList - everything again appears fine.
So the problem is I think with threading and the NotifyPropertyChanged events being lost when using certain datasources, in certain ways (wish I could be more definitive than that!)
I'm going to keep researching better ways of resolving this than copying the IList to the IBindingList - maybe I need to learn about thread marshalling.
Edit
I've now developed a solution that solves the issue and think I understand what was confusing me - it appears that anything but basic property databinding doesn't play nicely for lists that aren't derived from BindingList - as soon as I was trying to databind to properties that fired chained NotifyPropertyChanged events, things went haywire and my events got lost.
The data access solution I have now is using a variation of the Rob Conery IRepository pattern, returning my collections to be bound as a custom class I made, a SortableBindingLazyList that derives from BindingList, implements the Sort Core methods and also stores its internal list as a query, delaying the list materialisation.