Skip to main content
Home Forums Silverlight Programming Report a Silverlight Bug CommittingEdit event in DataGrid in RC0
53 replies. Latest Post by balukr54 on January 15, 2009.
(0)
brauliod
Participant
1167 points
471 Posts
09-27-2008 3:52 AM |
CommitingEdit event seems to be missing on RC0 is there any other way to execute the same operation?
amit_pal...
1150 points
201 Posts
10-01-2008 8:22 AM |
I am also facing the same issue? CommitingEdit seems to be missing. In another thread, it was mentioned that this has been there in the Breaking changes. Not sure, why this was not added to the Breaking changes document?
Any workaround for the same?
Jonathan...
All-Star
24581 points
2,409 Posts
10-02-2008 5:41 AM |
Hi Brauliod,
After dipping into its reflected source code, we are failed to find out the alternative way. Therefore, we need to handle it manually by modifying the template and attaching events to the template.
Best regards,
Jonathan
10-02-2008 10:11 AM |
Could you provide a sample?
Is this going to be fixed on the RC1?
Then, right now nobody can use online editing on a datagrid?
10-02-2008 11:48 PM |
brauliod:Then, right now nobody can use online editing on a datagrid?
Currently, it is not supported.
brauliod:Could you provide a sample?
We can simple modify its template and add a TextBox. Then do what we want on its events.
<data:DataGridTemplateColumn Header="Command"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding FirstName}"></TextBlock> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox Text="{Binding FirstName}" LostFocus="TextBox_LostFocus"></TextBox> //you can detect other events. </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn>
10-03-2008 1:51 AM |
Thanks for the sample Jonathan,
What I don't understand is:
Why then there is an edit data template / two way Binding / Context ? On Beta 2 I have been written an article about online editing using Silverlight Data Grid. Is this going to be fixed on the next release or SL2 DataGrid will remain an a readonly dataGrid?
10-03-2008 2:06 AM |
No official document is exposed to describe this, but we are confident that it will be fixed or implemented by another way. Thanks for understanding.
10-06-2008 7:23 AM |
Thanks Jonathan
I will delay the implementation of online editing in my project until a new version or doc is published.
Could you please notify us when that article / doc is being published? If finally this is not going to be fixed on the RTM (readonly DataGrid), Could you notify us as well ? (I have in mind a quick and dirty workaround, place a modal control above the row to edit including the fields to edit, very bad approach :-().
10-06-2008 11:39 PM |
I will keep my eyes on this. I will try my best to notify our community members. However, we highly suggest that you'd better go to Scottgu's Blog to obtain the latest info.
dimdim
Member
22 points
21 Posts
10-12-2008 4:01 PM |
I know it's not perfect, but you can use IEditableObject.EndEdit. If you want keep editing of the current selected item you can reselect it (in a DispatcherTimer.Tick event).
CoderX
154 points
89 Posts
10-13-2008 12:14 PM |
What do you mean by "online editing"? Do you mean the ability to edit items in the DataGrid and save the results (back to your server or whatever)? Or do you have a special meaning for "online editing" that I am not familiar with?
I have fully editable (save back to server) DataGrids in RC0 (and previous betas) without the use of any Editing events whatsoever. What I do is subclass the ObservableCollection (I call it SuperObservableCollection) to make it notify me of edits within the properties of its collection items (using INotifyPropertyChanged). A SuperObservableCollection is used as the ItemsSource for my DataGrid. In this fashion I am notified of any change to the underlying datacontext and can save it as I please, no editing events required.
I would be happy to post code for SuperObservableCollection if you wish.
If that's not what you're after, let me know what you mean by "online editing".
10-14-2008 2:54 AM |
Thanks,
That's exactly what I'm looking for, if subclassing observacollection and hooking up to some events gives a good solution, great.
The Grid it's supossed to give you events and functionallity to perform online editing, but the Ms Support team, told me that there is no official way to do this with the Grid currently, that they expect this will be published somewhere in time.
Thanks
Braulio
Jobin_koshy
2 points
4 Posts
10-14-2008 3:13 AM |
Hi,
It would be gr8 if u pass the code since i'm also lookin an alternative for the committing edit event in RC0.
jemiller
445 points
237 Posts
10-14-2008 12:42 PM |
I think "online" editing should be "inline" editing. Meaning, editing of data in the DataGrid itself.
10-14-2008 2:50 PM |
Yes, inline is the exact term. Sorry my english is quite shitty :-).
10-14-2008 7:27 PM |
Ok here's the quick and dirty for a SuperObservableCollection so you can get started. I'll try to find time to expound on this method later:
You'll need the following class. I stripped it to its essentials, but you can add back in more methods as desired:
public class SuperObservableCollection<T> : ObservableCollection<T>
{
new public event NotifyCollectionChangedEventHandler CollectionChanged;
public SuperObservableCollection() : base()
}
public void Append(INotifyPropertyChanged item)
item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
Add((T)item);
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, sender, sender, 0));
Once you've got that you'll need to make sure that any class you put in a SOC implements the INotifyPropertyChanged interface.
public class FeatureSelection : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private bool selected;
public bool Selected {
get{ return selected; }
set
selected = value;
NotifyPropertyChanged("Selected");
private void NotifyPropertyChanged(string propertyName)
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
Then you can add items into your SOC using the Append method (rather than Add):
private SuperObservableCollection<FeatureSelection> features = new SuperObservableCollection<FeatureSelection>();
features.Append(f);
Bind your SOC as the ItemsSource to your DataGrid.
FeaturesDataGrid.ItemsSource = features;
Subscribe to the CollectionChanged event of the SOC and from there you will be notified of any changes to your data.
features.CollectionChanged += new NotifyCollectionChangedEventHandler(features_CollectionChanged);
I think that about covers the basics. Let me know if you have questions, or if I forgot something.
10-15-2008 2:11 AM |
Good stuff !!! Thanks
Just a question, I use to consume WCF services, the proxy generated already maps the list to ObservableCollection, but... if I want to use that ObservableCollection on a Grid using a "CoderXSuperObersvableCollection" do I have to copy the collection into your new Observable...?
10-15-2008 3:14 PM |
Yes, you'll need to copy it over. You're going to have to any way to use the new class that implements INotifyPropertyChanged.
The alternative would be to write your own proxy to do it directly, but that might be more than you want to do.
The nicest thing that could happen is for Microsoft to roll this functionality into the ObservableCollection itself. Honestly, I'm surprised it's not already in there.
10-15-2008 4:49 PM |
If you want you want the service proxy classes to use your own collection instead of ObservableCollection, I think you can do it by modifying Reference.svcmap which is located in the Service References folder. You would change the following line to use your collection instead.
<CollectionMappings> <CollectionMapping TypeName="System.Collections.ObjectModel.ObservableCollection`1" Category="List" /></CollectionMappings>
I haven't tested this with Silverlight, but, I know it works with normal .NET. This is the file that gets modified when you right-click on a service reference and select "Configure Service Reference...' After you do that, I think you need to do an "Update Service Reference."
10-15-2008 4:55 PM |
To get it to work that way you would need to modify SuperObservableCollection so that it uses the normal Add() related methods rather than Append().
xiard
75 points
45 Posts
10-16-2008 9:04 AM |
Thanks for the excellent advice on the SuperObservableCollection. That got me pointed in the right direction for dealing with the lack of OnCommittingEdit.
I did run into some issues. In particular, the hooked event handlers keep firing if I don't clear them out when I replace my collection. In my case, I'm using ADO.NET Data Services in my Silverlight client. When I need to refresh the data from the server, I wipe out my current SuperObservableCollection and replace it with a newly created one with new data. If I don't kill all of the event handling hooks I setup, then the hooks keep firing.
Here's my modified version of SuperObservableCollection that handles that for me. I also created a new version of Add rather than defining a new Append method:
public class SuperObservableCollection : ObservableCollection { #region Item Watching PropertyChangedEventHandler m_handler = null; PropertyChangedEventHandler Handler { get { if (m_handler == null) m_handler = new PropertyChangedEventHandler(item_PropertyChanged); return m_handler; } } void HookItem(T item) { SetupItemHandler(item, false); } void UnhookItem(T item) { SetupItemHandler(item, true); } void SetupItemHandler(T item, bool unhook) { INotifyPropertyChanged notify = item as INotifyPropertyChanged; if (notify == null) throw new ArgumentException("item must implement INotifyPropertyChanged."); if (unhook) notify.PropertyChanged -= Handler; else notify.PropertyChanged += Handler; } void item_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, sender, sender, 0)); } #endregion #region Redefine ObservableCollection methods/events new public event NotifyCollectionChangedEventHandler CollectionChanged; new public void Add(T item) { base.Add(item); HookItem(item); } new public void Insert(int index, T item) { base.Insert(index, item); HookItem(item); } new public bool Remove(T item) { UnhookItem(item); return base.Remove(item); } new public void Clear() { foreach (T item in Items) UnhookItem(item); } #endregion }
Thanks again for your help!
David Cater
10-16-2008 1:23 PM |
jemiller:If you want you want the service proxy classes to use your own collection instead of ObservableCollection, I think you can do it by modifying Reference.svcmap which is located in the Service References folder....
If you want you want the service proxy classes to use your own collection instead of ObservableCollection, I think you can do it by modifying Reference.svcmap which is located in the Service References folder....
Excellent tip. I'll have to give it a try.
And yes, you would need to override the Add method as you suggest.
10-16-2008 2:45 PM |
I just ran across this blog entry which might be of interest.
http://blogs.msdn.com/scmorris/archive/2008/10/15/post-beta-2-breaking-changes.aspx
Who Is Affected: Silverlight 2 Beta 2 managed applications that use the DataGrid.
Explicit Binding is required to implement these 2 events correctly. Since the Silverlight Binding does not support explicit Bindings, these events were removed. They will be resurrected when explicit Binding is supported.
The DataGrid.CancelingEdit and the DataGrid.CommittingEdit events can no longer be used. It is recommended that you use IEditableObject to track when a commit has occurred.
10-16-2008 2:50 PM |
David-
You're welcome. Glad to see I've been able to help a few people. Having a community like this is essential for effective development.
Excellent implementation. Thank you for posting it. My actual implementation is a bit more fully featured than I posted, but I wanted to keep it simple to get people to the heart of the idea. Your enhance version cleans it up and rounds it out quite nicely. Good work!
10-16-2008 8:06 PM |
I am not having much luck with the IEditableObject suggestion. DataGrid doesn't seem to call it in the places where I would want it to be called. For example:
So IEditableObject doesn't really seem to serve the same need that CancelingEdit/CommittingEdit served.
David
10-16-2008 8:18 PM |
Seems pretty broken. Why would you have to press the ESC key twice instead of only once? Microsoft must really be in a rush to bring this stuff to market. Even ComboBox seems to have major issues. I hope they get it to work the way one would expect it to at some point. Given the fact that they already released it, they will have problems if any of the interfaces need to be changed. I think that's probably why they got rid of some of the events. They probably weren't sure it worked in all the cases that it should, so, they pulled it for the time being.
10-16-2008 8:19 PM |
On a side note, is anyone else receiving multiple emailed copies of the posts? I'm getting three copies of every post for some reason.
10-16-2008 8:26 PM |
Yes, I'm getting 2 or 3 copies.
D.
10-17-2008 3:05 AM |
Jeje a good "workaround" for this mail mess is to set in the settings your e-mail account to a GMail one, at least all the messages in the same thread are grouped into a single row, less annoying stuff :-).
balukr54
124 points
143 Posts
10-28-2008 7:01 AM |
Hi All,
I am dynamically adding columns to data grid from our code behind. I found your solution in the silverlight.net forum saying that we can use the Textbox_LostFocus event in a customtemplate. Your code is given below
How can i add an customtemplate to each and every datagridtextcolumn whenever i make one? Expecting your reply.
Thanks in advance
Balu K.R
10-28-2008 7:15 AM |
Mmm... interesting, I haven't tried that yet, I think this posts can shed you some light (
Defining a DataGrid Template Column
There are two ways to dynamically create a template column for a DataGrid. One is to load in the CellTemplate and CellEditingTemplates as DataTemplates from resources, and the other is to construct the DataTemplates on the fly using XamlReader.
http://www.silverlightshow.net/items/Defining-Silverlight-DataGrid-Columns-at-Runtime.aspx
http://blogs.msdn.com/scmorris/archive/2008/04/14/defining-silverlight-datagrid-columns-at-runtime.aspx
HTH
10-28-2008 8:26 AM |
Hi Brauliod
i am giving my code below. i was using commiting edit to update the grid.i need to find some workaround.so i tried using template column as you suggested , but i am not able to bind the templatecolumn.i need to bind it dynamically.
dgDetails.Columns.Add(dtextcol);
thanks in advance for your help.
10-28-2008 8:33 AM |
What I did was to bind it in the loaded event of the textbox, and the perform the update in the lost focus.
The official Ms solution is to use IEditable object
http://blogs.msdn.com/scmorris/archive/2008/10/14/silverlight-2-datagrid-is-released.aspx
10-28-2008 8:59 AM |
Hi ,
i tried the way you suggested but still didnt find a solution.is there any problem in my approach?
C#.
dtemplateColumn.Header = header;
dtemplateColumn.CellEditingTemplate =
dtemplateColumn.Binding = bind;
dgDetails.Columns.Add(dtemplateColumn);
thanks in advance.
10-28-2008 9:32 AM |
balukr54,
Why exactly are you trying to hook the LostFocus event? Are you trying to copy the data from the TextBox in the edit template back into your bound object? If so, then I think you are probably trying to do something unnecessary. You can do a two-way binding between the TextBox's Text property and the FirstName field in your source object. The basics are:
That should be enough to establish the appropriate two-way binding between your TextBox and your object's property. If you ALSO need to know in your data grid that that property has changed, then you should use the SuperObservableCollection that CoderX introduced above.
Or is there another piece of the puzzle that I am missing?
If you really do need to add event handlers to the elements of the grid row, another option is to walk the visual tree for the row (using VisualTreeHelper), find the element you want and hook the appropriate event. The trick is figuring out when to do that. I hook all my rows, but I do it for drag/drop purposes; i.e., not in edit mode. For me, I do the following:
Good luck!
PS: CoderX, are you at PDC in Los Angeles this week by any chance?
10-28-2008 9:46 AM |
And actually, the binding you have from the TextBox to FirstName should be working to copy the value in the textbox back to the FirstName property. The TwoWay binding with INotifyPropertyChanged is only necessary if you want to be able to change the FirstName property via some other mechanism and have that change be reflected in the TextBox.
So I guess my real answer is: inline editing should be working without hooking LostFocus. What problem are you having?
10-28-2008 10:24 AM |
Well inline editing sould be working without hooking lostFocus. We have other two approaches:
There's no perfect approach, altough the best approach seems to be CoderX one.
10-28-2008 10:36 AM |
One thing I found that is tangentially related is that if you are using a non-Microsoft web service such as a JAX-WS web service and you configure the service reference to use your own custom collection instead of ObservableCollection<T> it will be ignored. I submitted a bug report and it was immediately closed with no comment. Thanks Microsoft, much appreciated. Submitting bug reports to Microsoft is a waste of time. I have submitted many and only a few by coincidence were fixed. If you run into bugs, don't waste your time filing a bug reports. The release of Silverlight is proof. ComboBox doesn't even work. It's all about market share and getting a product out. It has nothing to do with the quality of the product.
10-28-2008 10:54 AM |
A Microsoft guy (somewhat inadvertently) provided some insight into the Microsoft Connect issue here at the PDC yesterday. Nothing earth-shattering or shocking, but I figured I would pass it along. It sounds like Microsoft pays a good bit of attention to the statistical reports surrounding Microsoft Connect at internal meetings. Furthermore, the more votes a Connect bug gets the more likely it is to be addressed. So...
a) They probably have an incentive to close the Connect bugs quickly when possible. There may not be a corresponding disincentive for ensuring bugs are addressed accurately, if there is no chance for subsequent feedback after the bug has been closed.
b) If you want your bug addressed, hope other people will vote for it or actively be an advocate for driving people to vote for it.
10-28-2008 10:58 AM |
Yes, about the TextBox, sorry you are right two way binding should be enough.
I use the Load / LostFocus approach to fill up combo's (enumeration is on another itemsource). Not sure if maybe there is a good approach (at the time wrote that code seemed a good one).
By the way some days ago a webcast about datagrid inline editing was published, I have to take a look :-).
10-28-2008 10:59 AM |
Yes, working with the ComboBox is a pain in the neck, fortunately some good fellows has published work around (some of them are dirty hacks but at least you get it working :-) ).
10-28-2008 11:34 AM |
xiard: Why exactly are you trying to hook the LostFocus event? PS: CoderX, are you at PDC in Los Angeles this week by any chance?
Why exactly are you trying to hook the LostFocus event?
I'm not sure why balukr54 is hooking to the LostFocus event, but I do know that in order to avoid the dreaded disappearing rows bug you do have to set focus in a DataGrid to the DataGrid itself. Maybe that's what he's referring to, maybe not.
Sadly I am not at PDC. The timing was such that I have a ship date next week and thus am strapped to my desk with a Mt. Dew IV and toothpicks propping my eyes open. I will be at Seattle Code Camp next month though if any one wants to get together.
10-28-2008 3:49 PM |
I feel for you, man. Good luck with it. Too bad you're missing it...it's a good conference so far. Lots of interesting stuff coming out (primarily Azure and C# 4.0 changes, I would say).
10-29-2008 12:18 AM |
hi Coderx, I am looking for inline editing of a datagrid. i did it using committing edit event.looking for a substitute for that event.
10-29-2008 1:51 AM |
Hi xiard, I use a List (Dictionary (string, string)) as the item source of my datagrid. This is because, i need to add new columns in the datagrid at run time. [The angle brackets was not appearing once i posted. Thats why i use the simple brackets instead of angle brackets of "List (Dictionary (string, string))" ].
The modification in grid was not getting updated into the List (Dictionary (string, string)). Thats why i wrote code in the committingedit event of datagrid in silverlight2 beta2 to update Dictionary.
In your example you used class property to bind it with the datagrid column. Can we create properties of a class at run time for this purpose? If so i have to change my whole code.
Is there any way to update the List (Dictionary (string, string)) whenever user do modifications in datagrid ?
10-30-2008 12:33 AM |
Hi All, I Found a solution for committing edit event.
private void dgRecordTypes_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
e.EditingElement.LostFocus += new RoutedEventHandler(EditingElement_LostFocus);
private void EditingElement_LostFocus(object sender, RoutedEventArgs e)
var newValue = e.Source as TextBox
hope this helps.
thanks
Balu.
10-30-2008 11:19 AM |
That does sound tricky. In WPF I've used Emit to create assembnlies on the fly, and ITypeDescriptor (I think that's right) to present arbitrary type information for my objects on the fly, but I don't know if Silverlight has those capabilities.
Thanks for the info on PreparingCellForEdit. Nice job!
11-04-2008 12:05 AM |
Hi
I am getting another bug in inline editing.If the user is editing a cell and press tab to move to next cell the mouse control shifts to browser address bar and the row being edited disappears. Is there any workaround for this issue.
How can i prevent the control being shifted to adress bar on tab press.
Escape enter key all are working fine.
Please help
Balu
jiafeng
8 points
5 Posts
11-04-2008 10:23 PM |
try setting TabNavigation="Local" in your datagrid
11-05-2008 1:06 AM |
Jiafeng its not working.
How ever i fixed it by setting tabindex to -1. but the issue is that tab navigation is disabled.:(
regards
balu
11-05-2008 5:55 PM |
make sure all cells have cell edit template defined if your datagrid is templated, tab navigation is only available in edit mode. please have a look at this thread
http://silverlight.net/forums/p/28726/112453.aspx#112453
11-05-2008 11:31 PM |
Hi jiafeng
I am using 4 datagrid .tab is working fine for all other datagrid :O. i am setting the itemsource in the same manner. i am not able to track why onlyone is not working.
thanks FYI
ilbusca
4 points
14 Posts
01-15-2009 6:04 AM |
Hi guys, if enyone is still interested i've found a good workaround for datagrid inline editing.
for tab navigation problem, just don't let the datagrid be the last element of a panel.
bye
Fabio
01-15-2009 6:13 AM |
hi Fabio.
it would be great if u could provide the idea or the sample code.
i have a solution but its not as much efficient.
balu.