January 27, 2012 09:45 by
Scott
I was doing some work with Silverlight the other week which involved using UserControls where the control named itself. That is, a situation such as;
<UserControl x:Name=”foo”>
<!—Content of control –>
</UserControl>
and, under unpredictable circumstances I was finding that I kept hitting a semi-random error when running my code which was something along the lines of;
“The name already exists in the tree: foo”
I spent an awfully long time on this and hence the blog post to try and perhaps save you some time in the future. I took long enough on it to come up with a simple repro scenario which looks something like this;
and so in words I have a ListBox which displays instances of UserControl1 and that control is just a StackPanel which contains 2 instances of UserControl2 and that control happens to name itself in its definition.
I found that if I ran this application a few times then sometimes it would work fine and sometimes it would fail with the dreaded exception and so I asked internally whether that was expected and it was confirmed as a bug in the Silverlight 4 runtime which has been fixed in Silverlight 5.
In my particular case, I could work around the bug anyway because I was naming that user control in order to use it for some bindings and the workaround I used was to create those bindings from code instead.
January 10, 2012 09:40 by
Scott
Lets start by updating the Code Behind of the Mainage.xaml .
Step 1:
Add a event handler for RowEditEnded .
This would give me the updated values of the Row . With this I would be able to update the update the cell and commit it. This event would help me trace the updated values . This event handler is to be added in the constrcutor of the Mainpage.xaml .
articleDataGrid.RowEditEnded += new EventHandler<DataGridRowEditEndedEventArgs>(articleDataGrid_RowEditEnded);
Step 2:
Implement the event handler for RowEditEnded .
I simply put the code to update the article and saving the context in the block .
void articleDataGrid_RowEditEnded(object sender, DataGridRowEditEndedEventArgs e)
{
try
{
if (e.EditAction == DataGridEditAction.Commit)
{
articleId = ((Article)e.Row.DataContext).ArticleID;
Article art = (from article in context.Articles
where article.ArticleID == articleId
select article).First();
art.ArticleID = ((Article)e.Row.DataContext).ArticleID;
art.AuthorID = ((Article)e.Row.DataContext).AuthorID;
art.Body = ((Article)e.Row.DataContext).Body;
art.Title = ((Article)e.Row.DataContext).Title;
context.SubmitChanges();
MessageBox.Show("Article was sucessfully Updated");
}
}
catch (Exception ex)
{
MessageBox.Show("Updating Article failed :" + ex.Message);
}
}
Step 3 :
Make sure you load the context in the Constructor of the MainPage class .
context.Load(context.GetArticlesQuery());
We are done. Run the App. Modify the Body or the Title . The Field would be sucessfully updated .
So we are done with Updation . I still need to add the validation to this .
Lets add validation then .
For this example we will go for basic validation . Just go ahead and add a Required attribute to the Domainservice Metadata that was generated .
Your Final Metadata class (DataDomainService.metadata.cs ) would look like as follows :
DataDomainService.metadata.cs
namespace SL2wayWCFRia.Web
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
// The MetadataTypeAttribute identifies ArticleMetadata as the class
// that carries additional metadata for the Article class.
[MetadataTypeAttribute(typeof(Article.ArticleMetadata))]
public partial class Article
{
// This class allows you to attach custom attributes to properties
// of the Article class.
//
// For example, the following marks the Xyz property as a
// required property and specifies the format for valid values:
// [Required]
// [RegularExpression("[A-Z][A-Za-z0-9]*")]
// [StringLength(32)]
// public string Xyz { get; set; }
internal sealed class ArticleMetadata
{
// Metadata classes are not meant to be instantiated.
private ArticleMetadata()
{
}
[Required]
public int ArticleID { get; set; }
[Required]|
public Nullable<int> AuthorID { get; set; }
[Required]
public string Body { get; set; }
[Required]
public string Title { get; set; }
}
}
}
Now give it a run .
Make the AuthorId field empty and press tab to move to the next field you would get a message as shown below :