Showing posts with label XAML. Show all posts
Showing posts with label XAML. Show all posts

Thursday, November 4, 2010

What’s the fuss around Silverlight about?

Since day one of PDC10 there has been a lot of press attention for what appears to be a change in strategy for Microsoft around Silverlight. As I’ve gotten several questions from people concerning the stories published by several respectable sources and how this would impact the business, I decided to write down my take on this.

The PDC10 debacle

So what are people on about? It basically comes down to two things. One is the “lack” of attention for Silverlight on the PDC10. The other is Microsoft announcing that they completely back HTML5. It was elaborated on by saying that there has been a shift in the strategy around platform independent web technology. Also, because there has not been an announcement on Silverlight 5, people are scared into believing there will not be a Silverlight 5.

Most people interpreted this by concluding that Microsoft will limit their investments in Silverlight to the Windows Phone platform. Let’s assume they are right in their conclusion. If that is true, then it’s devastating for all those developers and companies who have invested heavily in Silverlight in the past years.

My analysis on Silverlight

So how do I look at this? Well, there is a number of things I see differently from most people. Let’s have a look at some of those.

HTML5 vs Silverlight

A lot of people see HTML5 and think it replaces Silverlight for the browser completely. Having worked with both HTML4 and Silverlight and having looked into what HTML5 brings to the table so far (it’s not done yet), I have to disagree.

First of all most people that make this statement think of Silverlight as a platform for media and games, similar to Flash. However there is a lot more to Silverlight. For one it is a lot better suited for Line Of Business (LOB) applications. Another major advantage is that everything works and looks exactly the same in different browsers and on the desktop.

Another major advantage about using Silverlight for web developemt is that you can use one programming language across different tiers, complimented by one markup language. Compare that to HTML and you immediately spot the problem. Not only do you need HTML for markup, you need CSS for styling and Javascript for client interaction. To top it all off you need some server side language to work with data. That’s four languages for something that Silverlight does with two languages. Are the decision makers of IT-world paying attention? Less is definitely more in this case.

Because of all this, and a great IDE in the Visual Studio / Blend combination, productivity in Silverlight is much higher and more business logic focused than the classic web application. This allows developers to provide more value more quickly, making more money for the companies and their customers.

But Microsoft has given up on Silverlight, right??

Well, did they? Let’s look at some facts here.

First of all this statement is all based on Microsoft communicating their support for HTML as the only true platform independent technology. People think that this is change in strategy, but in fact it’s not. Let’s face it, that is just reality. The downside on Silverlight is that there is no complete support for all platforms. I’m not only talking about Linux here. It’s also about a lot of mobile platforms. And it’s hardly realistic to expect to get that support for all these platforms. It’s not going to be cost effective to do so. In my book, this statement is stating the obvious and it would be stupid to say anything else.

But will Microsoft stop investing heavily Silverlight because of HTML5? I don’t think so. First of all HTML5 is far from complete. It will take at least another ten years to make it to the main stream in it’s full glory. Second of all HTML5 will have trouble adapting, because it is a global standard and everyone wants to have their say about it. Silverlight doesn’t have this issue.

And then there is the business side of things. Microsoft has invested so heavily in Silverlight, it would not make sense for them to stop now. They have cranked out three major releases of Silverlight in the past two years, including tooling for Visual Studio and support in Blend. They have invested in the Silverlight Toolkit. They brought Silverlight to the Windows Phone platform. And recently they introduced Visual Studio LightSwitch, which can generate complete Silverlight applications. Really, they have hundreds of millions of dollars invested in Silverlight, with great success as a result. And frankly, there is no reason for them to stop doing so, for all of the reasons mentioned before. As long as it keeps selling software for them, they’ll keep working on it.

Conclusion

So we can conclude that Microsoft will not stop pushing Silverlight forward in the foreseeable future. However, it is up to decision makers to stick with the facts and not go with the press buzz, or they will be investing in the wrong technologies, loosing a lot of money in the process. And it’s up to developers to stand by their choice of technology. There really is no need to suddenly change anything.

Just remind yourselves, what made you choose Silverlight as a platform in the first place? Exactly.

Tuesday, March 16, 2010

MIX10 Keynote: Silverlight and Windows Phone 7

Yesterday there was a unique event on Schiphol Airport in the Netherlands.

What?? Your title says you’re talking about MIX10??

Just read on, it is about MIX10. Microsoft Netherlands organized, for the first time, an official get-together for a small group of people to come together and watch the MIX10 Keynote and I was fortunate to be one of those people. This article is about the keynote and the event in the Netherlands.

The arrival

As I arrived, I was expecting to be early, but to my surprise there were already about twenty people in the lobby waiting to get to the conference room where we would watch the keynote. It struck me that this was not your typical group of developers, but more a mix of different stakeholders for the information that was going to be released. I guess that’s why they call it MIX :-).

After a couple of minutes we were escorted to the conference room where, with about 35 people we would watch the keynote. I expected more people than that, but it was a bit short notice to get a larger group together. I received my invitation on Friday.

Pre-keynote

As we entered the conference room the live feed to Las Vegas was already displayed on the beamer and we could watch the performance of the world champion in JoJo’s. Sure, it was impressive, but I did get bored about 2 minutes into that and there was at leas another 10 minutes to go.

The Keynote!

Obviously the keynote is always presented by one of the top people at Microsoft and this year it was Scott Guthrie. I was pleased as it wasn’t some commercial hot-shot who can’t go into technical details. I have great respect for Scott. He seems to know what he’s doing :-).

The first couple of minutes where all about Silverlight and the successes it has had recently. I was seriously impressed with the Winter Olympics case that was presented and I was more impressed with the fact that the source for this is being open sourced on CodePlex.

There was also the eBay demo, where they announced a Silverlight app to more easily list items. It looked smooth, but the one question that stuck was, why didn’t you do that a year ago? The technology was already there. It would have been almost just as easy in Silverlight 3.

Next was the obvious announcement of Silverlight 4 RC. The announcement that Silverlight 4 RTM will follow next month wasn’t a great shocker as well. I was happy to hear that upgrading from Expression Blend 3 to 4 is going to be free.

After this there where some demos of the Windows Phone 7. I’d seen what the Windows Phone would look like before, so I wasn’t so interested, until an announcement was made that Silverlight 4 is the major platform for the Windows Phone 7. There where demo’s and that’s great. Scott slapped together the first second tweeter app in under eight minutes and with that displayed, not the power of the Windows Phone, but the power of the Silverlight platform. For Silverlight developers it also became obvious that the model that we all know and love, is no different for the Phone.

Another great thing that came across from the demos was the emulator. It looked like it would work easily, fast and exactly the same like the actual device.

Oh, and yes, there is the Marketplace where you, as a developer, can post your Silverlight applications, decide how you want people to experience the trial version and you can start selling your app. Details are still a bit sketchy, but there will be the opportunity to monetize your apps, either through selling or through advertizing.

When they announced that the tools for developing Windows Phone 7 applications in Silverlight are, and always will be free, it all came together. This is a full frontal attack on both the iPhone and the Android platform.

The other platform

To enable developers of games to provide a greater experience, Microsoft announced that the XNA platform is fully supported on the Windows Phone 7, including XBOX Live integration. Now you can port your XBOX game to the PC AND to the Phone with a minimal amount of work. Simply a great achievement.

Some demos where given, showing games across platforms and showing off the XBOX Live integration. It looked like a powerful platform for games, which, to me as a consumer, is a great asset.

After the keynote

After the keynote ended, there was a short break with drinks and discussion about what was presented. I found out there where both Silverlight adepts and Windows Mobile developers and business owners in the room, which explained the somewhat unusual mix of people.

We where then invited to have some of the dutch people attending MIX10 in person to do a Q&A. One thing that stuck was that the model you develop in in Silverlight is the same for the Phone. There where some tough questions about the Marketplace, which seems still a bit obscure at the moment, more announcements should be available later this week. Also there where questions about push notifications through a server platform. These will be provided for free.

After about an hour of Q&A we all had some pizza and talked some more about the proposition Microsoft has for the mobile market.

Conclusions

So Microsoft is taking on the mobile market, directly attacking both the iPhone and the Android platform. The big question remains, will they succeed? If you look at the philosophy behind the new Windows Phone 7 platform, then you have to conclude it is a better thought out platform than both the iPhone and the Android platform.

The iPhone actually looses the battle in terms of usability as there is no structure holding together the applications on the phone, were as the Windows Phone 7 supplies hubs centered around tasks you want to do with your phone. Microsoft did a good job taking a long hard look at the iPhone, though. They took what are considered the strongest points on the iPhone and incorporated them into their own platform. This includes the single custom application model, the capacitive touch screen and the all important marketplace.

In comparison with the Android platform it should be easy. Android allows users to run as many processes in the background as they like and shuts down those processes when the OS determines they are no longer used. This sounds like a great plan, but in practice turns out to be a real headache for the user. It seems to be going in the direction that Windows Mobile was heading. The only huge advantage Andriod has is that it’s open. This means that any vendor, any developer and any operator can do Android. Microsoft has given a very strict set of specifications that phones need to adhere to.

Basically they chose to be in between the choices made for the iPhone, one vendor, limited operators and limited developers resulting in a smooth user experience, and the choices made for the Android, unlimited vendors, operators and developers resulting in a not so great user experience.

Looking at the above and at how the platform is easier monetized because of the limited investments, the only potential issue that Microsoft has, it that they are late. On the other hand this may work to their advantage. Everyone experienced the good and bad of the other platforms before Microsoft comes with a more balanced solution. The future will show us.

A final word as a Silverlight Developer. Thank you, Microsoft, for making my personal investments in Silverlight worth while. And thank you, for providing us with free tools.

Thursday, October 8, 2009

Adventures while building a Silverlight Enterprise application part #25

In the previous episode I discussed how an enum can be used to encapsulate char values in a database, in this case using a Gender enum as an example. As cool as that was it does pose a problem with databinding in Silverlight that I'd like to share with you. Part of that explanation leads us into the realm of reflection (that would make for a cool blog title :) ) and then into some cool trick in binding, all to end with a bit of a dissapointment. So if you already feel depressed, stop reading now :-P.

The story
First there was a BussinessObjectBase. This class handles a lot of stuff around transporting data between the service and the client and back. It also helps in keeping track of property changes and notifies about them. It's a very generic class and it serves as a base class for all our 'business' objects.
In this case let's say there is a PersonBase class, that is derived from BusinessObjectBase. PersonBase is generated based on some metadata, so we don't want to touch this source. The PersonBase class has a property called Gender that is of type string.
Then there is the Person class, which was generated but is meant to be used for custom code, so this is where we will write some code to make our Gender available as a Gender instead of a string.
We could simply write something like this in the Person class:
private char GetGender()
{
string gender = base.Gender;
if (gender.Length == 0)
{
return DefaultGender;
}
return gender[0];
}

public Gender GenderValue
{
get
{
return (Gender)GetGender();
}
set
{
base.Gender = ((char)value).ToString();
}
}

Our intention here is to hide the base implementation of the Gender property and have our own implementation that returns an actual Gender enum. Nothing special so far.
Next step is to use this new property in a databinding scenario. Here is what the binding statement in XAML would look like.
{Binding Path=Gender, Mode=TwoWay}

Now if you'd try to use a binding statement like this and run the code, what would happen is, that you would get an AmbiguousMatchException, the reason being that the binding engine can't distinguish between PersonBase.Gender and Person.Gender.
What? But we wanted to hide PersonBase.Gender, right? Absolutely, but both properties are public, so both are actually available.

Reflecting on the 'new' property
To get a better understanding of why this was happening, I decided to write some reflection code:
object person = newPerson();
object personBase = newPersonBase();

Type personType = person.GetType();
PropertyInfo personGenderProperty = personType.GetProperty("Gender");
MessageBox.Show(personGenderProperty.GetValue(person, null).ToString());

Actually trying to get the value of the Gender property through reflection threw the AmbiguousMatchException, just like it did when databinding to it. Actually calling personType.GetProperties from the Immediate Window in Visual Studio returned both properties. Then the exception all of a sudden makes sense.

What might seem a bit akward is the fact that both properties are there. If I'd try to write string gender = somePerson.Gender where somePerson is of type Person then it would not compile because I can't implicitly cast this, proving that the base property is actually hidden. Still, having the property available is needed, because the derived class needs to be able to call the property in the base class.

Trying to bind to it anyway
Still, I needed to find a way to bind to this property. I came up with some simple solutions:
  1. Make the base property protected
  2. Rename one of the properties to remove the problem all together
  3. Find a way to distinguish between the two properties in databinding
The first solution doesn't work for me, because I can't touch this code (it was generated, remember?).
The second solution would mean that I'd have to rename the property in the derived class, which doesn't seem very nice.
The third solution was a long shot, but I had to give it a try. I did actually find this syntax to use for a case like this, however it wasn't very well documented, so I did some experimentation to get a better understanding of it. I started writing this in XAML:
{Binding Path=(local:Person.Gender)}

This failed with an exception telling me that this was an invalid value for the attribute. I was surprised an puzzled, because I read about other people using it and it is actually in the documentation like this. Some further investigation learned me that this only works on dependency properties. I've build a small example of this and it actually works very well, however...

...having a dependency property with all the plumbing involved is best done by deriving your class from DependencyObject (which contains stuff like GetValue and SetValue). I obviously can't derive Person or PersonBase from DependencyObject, because I have already derived them from another class. This means I now have to rename the property in the derived class :(.

You can find the example of binding to a new property here. Hopefully it is helpful to you. It was a great learning experience overall. Just to bad it didn't lead to a better solution for me.

Thursday, September 24, 2009

Adventures while building a Silverlight Enterprise application part #23

Today we look into how collations in Sql Server bugged me while trying to get code generation to work on a database different from what it was originally build on. We also look at how I solved the problem (which is with some cool C# and WPF code).

The problem context
Lets take a look at the big picture first, so we all are on the same page as to why I ran into this problem. In the application we are building we have multiple databases to store our LOB data in. Depending on someones authorization, it's possible he or she has access to one or more of these databases (or sometimes only subsets of these databases). Because of this, we needed some central data store to hold information on security, the complete installation and on where what LOB database is and what data is in it. We call this data store the Repository and stated that any data we need to go across LOB database boundaries, should be in the Repository.

So far, so good. In the early stages of the project we build a WCF service, based on Entity Framework, that allows us to do any data operations on the LOB databases in a generic way. To achieve this we build a code generator to generate all the business classes we needed. The code generation process we use for the service is based on the fact that we use a automatically generated EF model. In other words, the EF model is a direct depiction of the SQL Server data model. Because of this fact we can extract metadata from SQL Server to feed our code generation process. To do this, our database guys build a script that extracts the metadata from SQL Server (using the system views) and insert it into a separate database which we use to power our code generation.

Up to this point, still no problems. Now what we wanted to do, was copy all the code we've build to access the LOB databases and from that build a WCF service to access our Repository and because of that I needed to generate business classes from the model as it is inside our Repository database. Now normally we create and update our database models through a Sql Server 2005 project in Visual Studio 2008 and do schema compares.
However, data is added to this metadata by several people and in that case we tend to use a backup to distribute this data, which was exactly what I did when preparing to add the metadata from our Repository.

The probem
After restoring the metadata database is when the problems started. I needed to alter the stored procedure written to extract the metadata from a database to change the source database name to make it access the repository database. As soon as I ran the alter procedure statement to update the stored procedure, I got several collation conflict errors. It turns out that a backup I got from the Repository database was created in a different collation, from the one I normally use. To be more specific the Repository database was created with Latin1_General_CI_AS (my local default) where as the metadata database was created with SQL_Latin1_General_CP1_CI_AS.

To solve this issue I would need to go through each column one by one and change the collation. Because the only data accessed from the Repository is in system views and you can't (and don't want to) change their collations, I had to change the collations on the metadata database. I didn't feel much for doing this by hand and because I foresee this happening more often, I figured I might aswell write a small tool to handle this for me. Here is a screen shot of what it looks like:
Basically it allows you to type in a Sql Instance name, after which it retrieves the database list from that instance and also it retrieves all available collations to fill the two comboboxes. As soon as you select a database and at least a source collation, you can then click the Find Columns button to retrieve any columns with the source collation. After you've selected a target collation and unchecked whatever columns you do not want to change, you can then click the Change Collations button and it will trigger an alter table / alter column query to try and do that for you.

I guess what gives this tool it's flair is the use of some queries directly on ADO. Here is a snippet of code with these queries:
private const string GetAllDatabasesSqlCommand = "select name from sys.databases";
private const string GetAllCollationsSqlCommand = "select name from ::fn_helpcollations()";
private const string GetAllColumnNamesSqlCommand = "select o.name, c.name, t.name, c.max_length, c.is_nullable"
+ " from sys.columns c"
+ " left join sys.objects o on c.object_id=o.object_id"
+ " left join sys.types t on c.system_type_id = t.system_type_id"
+ " where c.collation_name=@collation_name";

The first query retrieves all database names. This obviously only works when connected to the master database.
The second query returns all collation names. This can be done on any database (it should always return the same list).
The final query finds all columns that use a specific collation. The result set includes the table name, the column name, the type name, the max length and whether or not a column can contain NULL. This is all the information needed to generate an alter table alter column statement which changes only the collation.

Something I never used before was the SqlConnectionStringBuilder class to dynamically create my connection string. Here is the code I used for that:

SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder();
connectionStringBuilder.DataSource = hostnameTextBox.Text;
connectionStringBuilder.InitialCatalog = MasterDatabaseName;
connectionStringBuilder.IntegratedSecurity = true;

As you can see, using this class is really straight forward. Another thing I never used before was the ChangeDatabase method on the SqlConnection class. This came in handy as I could simply keep one connection throughout the flow of the application and switch databases quickly.

I've uploaded the code here for your viewing pleasure. Note that this tool was slammed together in a hurry so most of the code is in code behind for the main window and most of it isn't very well written, however there are some nice concepts in there as well

I hoped you enjoyed yourself again. I know I have.

Wednesday, September 16, 2009

Adventures while building a Silverlight Enterprise application part #22

Yesterday I needed to check the available style keys in our main app.xaml file and see which are no longer needed. As there currently are 66 style keys in that file and it's growing, I didn't feel much for taking each key and searching through our source code to find out. Time to build a small tool. This article describes how I build this tool.

Requirements

The tool needs to be able to search a directory tree for files with a certain extensions (.xaml*) for a pattern or literal string. Before it does this it also needs to be able to open a .xaml file and retrieve any style elements so it can then read their keys.

To achieve this, two classes are needed. One class will read a .xaml file and get all keys from style elements and the other class will search trough the file system for files containing these keys.

Building it
I'll spare the obvious details and dive right into the highlights. To read the keys from style elements in basically any xml document, I used LinqToXml. Here is the code I used:
private void LoadStyleKeysFromDocument()
{
XNamespace winFxNamespace = "http://schemas.microsoft.com/winfx/2006/xaml";
XName keyAttributeName = winFxNamespace + "Key";

var result = from node in _document.Descendants()
where node.Name.LocalName.Equals("Style")
select node;

var distinctResult = result.Distinct();

StyleKeys.Clear();
foreach (XElement styleElement in distinctResult)
{
StyleKeys.Add(styleElement.Attributes(keyAttributeName).First().Value);
}
}


The first two lines make an XName object that is needed to include the xml namespace when retrieving the x:Key from the element. Note that this works independently from the prefix (x) as it was assigned in the document. This means that this code will still work if someone would decide to change the prefix on this namespace.

Next, a Linq query is used to retrieve any nodes in the document that have the name Style. The query is followed by a statement to make sure I only get unique results.

Finally I fill the StyleKeys collection with any key attributes value found inside an element in the query result.

Searching for a particular pattern in the file system is done in the following method:
public void Search(string pattern, string rootFolder, string fileFilter)
{
// Get all files matching the filter
string[] fileNames = Directory.GetFiles(rootFolder, fileFilter, SearchOption.AllDirectories);
// For each file
foreach (string fileName in fileNames)
{
// Open file
string fileData = File.ReadAllText(fileName);
// Match pattern
MatchCollection matches = Regex.Matches(fileData, pattern);
// Register count
PatternSearchResultEntry resultEntry = newPatternSearchResultEntry()
{
FileName = fileName,
HitCount = matches.Count,
Pattern = pattern
};
Results.Add(resultEntry);
}
}


As you can see, the first line gets all the filenames that are anywhere in the directory hierarchy below the supplied root folder.
Looping through the filenames, I simply load all the text from each file and use the Regex class to count the number of hits. By doing so, this code is also very useful to find hit counts for other patterns.
All the results are added to a collection of a struct called PatternSearchResultEntry.

So thats the business end of things. Obviously we need a user interface of some sort.
I chose a WPF interface, because I like data binding.
To retrieve user input for the style file and the folder to look in, I build a class called BindableString, which contains a Name and a Value and implements the INotifyPropertyChanged interface. It allows me to create instances of these and bind them to my UI. This way I have a central point to access this information without having to worry about updates, etc..

To do the actual work I wrote the following Click event for a button:
private void analyseStyleUsageButton_Click(object sender, RoutedEventArgs e)
{
XamlStyleKeyReader reader = newXamlStyleKeyReader();
reader.ReadXamlFile(_stylesFilePath.Value);

PatternSearch patternSearch = newPatternSearch();
foreach (string styleKey in reader.StyleKeys)
{
patternSearch.Search(styleKey, _searchRootDirectory.Value, new string[] { "*.xaml" });
}

CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(
patternSearch.Results);
if (view.CanGroup)
{
view.GroupDescriptions.Add(new PropertyGroupDescription("Pattern"));
}
analyseStyleUsageDataGrid.ItemsSource = view.Groups;
}

It basically instantiates the XamlStyleKeyReader class and loads the style file in it. Next it instantiates the PatternSearch class and kicks of a search for each style key available in the XamlStyleKeyReader.

The code after that groups the results based on the search pattern. The reason I did it this way is because it is not very transparent to bind to the result of a group in Linq. Binding to this is easy once you know how. As you can see the items source for the datagrid that displays my results, is actually the collection of groups.
This collection is declared as having objects, which isn't very helpful, however diving into the API documentation reviels that this collection contains instances of the CollectionViewGroup class. From that class I need the name (obviously) and a hit count, which of course it doesn't have.
To get a hit count I bound to the Items property from the group, which contains all the items that belong to that group and then I use a value converter to get the total hit count for that group.

I've uploaded the complete source for this tool here.

Be aware that this tool is far from finished. I would like to save the last settings and have some progress indication, which means moving the search code to it's own thread. Styling of the UI can be improved, etc., etc.

I do hope you find this code useful and you've learned something along the way.

Sunday, September 6, 2009

Adventures while building a Silverlight Enterprise application part #21

I came back from a short vacation today and read this post from Tim Heuer. I then realized that in all twenty parts I've written on our adventure of building a Silverlight Enterprise application, I've actually never elaborated about why and how we chose Silverlight and how we (or at least I) learned to use Silverlight technology. So now seems as good a time as any.

Let's be a lazy author and just follow the questions that Tim put up there.

Decision resources
Obviously when you go about to start a project you have to decide on what you are going to use and why. If you are looking at Silverlight, what factors into your decision?

In our case, one of the most important topics was to move from a client-server based solution with a (very) fat client to a multi-tier solution with a web based client. The first choice was to go with DotNetNuke as some experience was already available, however, as you may very well know, this uses regular ASP.NET Ajax like solutions, which we found very limiting in UI perspective. At the time Silverlight 2 was just about to come out of the Beta stage and we felt we should at least take a good hard look at it. We needed to have technology that was relatively easy to implement and yet have enough flexibility to make for a very useful UI.

So our major decision factors where:
  1. UI possibilities / user friendliness
  2. Development speed
  3. Flexibility
Why did your company choose to adopt Silverlight (or choose not to)? Was there another technology that was chosen to be better? Why/why not?

We choose to go with Silverlight because it checked the boxes on the above list. We felt it was easier to build a good user friendly UI with Silverlight, in comparison with ASP.NET / Ajax. Also we experienced in our prototyping / prove of concept face, that building a UI with Silverlight is taking less time as well, because of the use of XAML and C# only. No HTML or JavaScript code made live a lot easier for us.

Another elementary aspect of Silverlight proved valuable to us. It was the fact that you can embed controls inside other controls and work with templating. In combination with declarative databinding this became an important topic for us during decision making.

Again we where comparing to DotNetNuke, which had some advantages over Silverlight as well. One of the things that DotNetNuke had which was considered an advantage, is the fact that you could than access the database directly from your client side code. In hindsight I'm glad that we can't do this with Silverlight and just have all the logic in a service layer. This proved to be much more flexible for a lot of scenarios we already ran into.

What is the most important thing in deciding if Silverlight is right? Feature set? Existing technologies? Rapid development? Other reasons?

At the time, Silverlight 2 was not exactly existing technology as it was just coming out of Beta. This was a concern for us, but the fact that this was Silverlight 2 and that there was already an active and growing community, combined with the fact that Microsoft had plans for updates layed out already, pulled us across. The feature set was definitely important. The way databinding is implemented is important to us, as we are building a data rich application. Also the controls available at the time as default, but also trough the Silverlight Toolkit and the fact that third party companies literally jumped at Silverlight 2 helped easing the choice even further.

Rapid development was obviously something that needed prove as no real world examples where available at the time. We build prototypes of several scales and found that it was indeed fast enough to build something with Silverlight 2, even without experience with the technology.

Learning resources
On learning – how do you best learn? Do you prefer “atomic” samples? These are the ones that you can just pop in and figure out a task-based situation (i.e. how do I open a file in Silverlight). Or do you prefer more of a “lesson plan” approach to things? This would be a series based on a task (i.e. Build a Media Player in Silverlight).

For me personally a lesson plan approach was new. I did part of the digg API sample series, but after several steps I lost interest, mainly because some of the topics where not of interest at the time and some of the topics where just to easy for me. This makes me lean towards atomic samples, altough as a starting place I can see why people like this lesson plan thing. Later on atomic samples are obviously the way to go. They have the advantage of showing only the bare minimum of implementation without the burden of having to go trough previous steps to understand code that was already there.

On medium – in either types of these learning paths, what is your preference? Video? Written step-by-step guides? Labs?
When you are completely new to a topic, watching a video is great. It takes away some of the effort of having to follow along with some article and just being showed how things work. This is also great for some more indept topics, with less code and more explanation.

If looking for a reference, or if I need to actually start coding on something, I do prefer written material, as it is a lot easier to just scan trough and look for that bid of code, or that bid of explanation you needed, instead of plowing trough twenty minutes of video trying to find that five second shot of the code you need.

I've tried labs in the past and I found that they are not my thing. I tend to get bored very quickly because usually the level of instructions is making things to easy. Also setting up to do a lab feels like a lot of work most of the time.

On topics – what are the top 3 topics you expect when learning a new technology? How do you on-ramp yourself when you know nothing about it? Do you expect to learn the tools first? Or jump right in to data access?

This is actually a very tough question to answer. It realy depends on what a technology looks like. When looking at Silverlight I felt that I already knew enough about the most important tool: Visual Studio 2008. Of course Blend became part of the toolset I use and over time I did watch videos and read tutorials on Blend to learn some tricks here and there. So for me, while learning Silverlight, diving right into important topics was very helpful. I do feel it is important to include tips on how to use tools, where this is important to the topic at hand.

For example if you are talking about databinding and data access, it is handy to demonstrate on how to do this in Blend including using sample data. If something like this becomes to elaborate, at least make sure you point out to the public that this is a handy feature they should know about and tell them where they can find more information about it.

Other notes
Something that bugged me for quite some time when getting started with Silverlight was the number of resources that where available for Silverlight 2 Beta 1 and 2. While being a great help to win over management to go with Silverlight, this made live a lot tougher when trying to find useful resources for Silverlight 2 RTM as a lot of times the important bits would not work in the RTM.

Something else that I found is that, altough silverlight.net is a great resource when learning Silverlight, it is a bit of a mess. Videos are not categorized in a way that makes them easy to find and there is not a proper search function on the site. Also I think it would be very helpful to have a search engine that can search for Silverlight content for your specific version only. So if I'm working on Silverlight 3, I might not be very interested on Silverlight 1.1 and 2 content. Or at times I might not care if it's Silverlight 2 or 3 content, because they are likely to be compatible any way.

As a final note I would like to encourage anyone who hasn't already done this, please go to the article of Tim Heuer and comment. Or you can comment on this article as well.

Tuesday, August 25, 2009

Adventures while building a Silverlight Enterprise application part #20

This post is about some of the less technical (a.k.a functional) stuff around code generation, especially when using XAML, it being in either Silverlight or WPF. This is a no-code post, that is intended to give you some food for thought when planning for code generation on different levels.

The basics
If you're involved in applications that have large amounts of, well, something, it may very well be feasible to use some form of code generation. You could use this for many things and most of them, if not all, have been done already. Some common items in software that may be candidate to code generation are:
  • Business objects
  • Screens / windows / forms in the GUI
  • Reports
  • Database scripts
And obviously there are a lot more. There are only two basic requirements to code generation. What you plan to generate needs to be in some format you can actually supply from some peace of code and what you plan to generate needs to have some form of repetitiveness to it.

The most common thing to generate is your Business objects. They tend to be very repetitive and as they are in some programming language it usually is enough to generate simple text. If you're application is based on some relational database, you might even be able to leverage the metadata in your database as a source for generating your business objects.

Setting goals
The first thing you should do when thinking about code generation is set goals. What I mean by that is you should think about not only what you're going to generate but also why. Is this generated code only a starting point and are you never going to regenerate? Or are you interested in regenerating code at some point? The answers you give on these questions have a big impact on how your generation process should look.

If you're generating only once, you need to make sure that any metadata you use in the generation process is definitive. Experience tells us this is nearly impossible to achieve, so at least make sure the impact of a change is as minimal as possible and also make sure your generated code is readable.

If you are going to regenerate, consider the fact that not only do you need to run the process and make sure you're not loosing any customizations on the generated code, you also need to make sure that any source of metadata is consumed again. More on that later. Another concern when regenerating is integration testing. When you regenerate part of your applications source, you've altered all that source and changes are something is going to fail because of it. Make sure you think about how you're going to at least test for failures, or better yet, prevent failures in the first place.

Have a business case
You may or may not have to pitch code generation in your organization, however you should always have a business case for a code generation process. What I mean by that is you should at least have some clue as to how much effort it will take to build the generation process and how much time it will safe you in the end. Basically you need to have a Return On Investment calculation, at least for yourself, before you go off and invest a lot of time into this. I know it may seem that you won't invest that much at first, but trust me, you'll most likely end up spending at least twice the time you figured before you actually set down and made a decent estimate.

When looking at this business case, make sure you do not only include the obvious. Everyone can figure out that it saves time not having to write a specific amount of code. What is getting left out a lot is the quality of the code that is generated. It's consistent, which means you can test one instance of the code and you'll know the rest will work. This also means it reduces the amount of bugs and if bugs are found in generated code, it reduces the amount of effort to fix these bugs.

Having worked for several software companies in different roles I know from experience that having less bugs is an even bigger win than spending less money on writing code. Having a bug doesn't only cost money, it also impacts reputation and customer satisfaction at some point. Having less bugs is good for everybody.

When things get tricky
You obviously can't generate every bit of code in your application, however most of us will be tempted at some point to try and generate something to hard. One of the most underestimated peaces of code to generate is part of the GUI.
Let's say you're building a Line Of Business application that has one hundred forms in the application that are being used for data entry. This is obviously a very common scenario. Not many developers like to go out and build that many forms. It just feels silly doing repetitive work if your job is all about automating repetitive tasks.

However, there is more then meets the eye here. Let's say you want to do this for a Silverlight application. At first glance, all you need to generate is some XAML for each form and it needs to contain some TextBlocks to contain the labels and some other controls to be used for input. All seems fine so far.
Now consider the metadata you need to actually generate this. You may say that you already have this as it is the same metadata you've used for generating your business objects. Is it? I doubt that. The only thing your business object tells you is what fields it contains and what types they are. They don't tell you anything about their position in a form. There is no information about any special behavior that this one specific control needs different from most others.

All that extra information needs to come from a functional designer, it being some application expert or even one of the developers in the team. Now let´s say you have this metadata in some usable form. You´re still not capable of generating a functional form. Now you need to bind to your business objects. Initially this isn´t that hard, but things start to get complicated when your datamodel evolves or when the functional designer desides to link in that one field from some other business object on the same form, because that is easier for the user.

Now let´s say that you even got that under control. Now you still need to ty in behavior. You need to attach events, which means you also need to generate the code behind for your application, but you also want to be able to extend the code behind at some point. The metadata you need for that process has to come from a developer at some point.

If you now look over the big picture for generating XAML forms, you have not one but three sources of metadata:
  • The datamodel
  • A functional designer
  • A developer
And these three sources of information need to be brought together so they can be used in a single generation process. Building something like this quickly becomes a project on it's own, rather than just a meens to an end.

Putting it in perspective
So shouldn't you do this? That's a good question and there is no simple yes or no answer. It all boils down to your ROI calculation as I explained it earlier. How much effort goes into building and implementing this way of building your GUI in the organization? And how much effort is going away from building and maintianing it in a traditional fashion?
Obviously if you have an increadibelly large application, this might actually work, but another case in which this may work is if you're a one-man-show. If you do the datamodel, the functional design and develop the application, then this might just be worth the effort. The reason for that is because you control all the variables and there is no team to keep in check on how to work with this.

So what if you figure out this is not a good approach for your project, should you just go off and build a hundred forms by hand? Well, not so fast. If you can eliminate one or two of the sources of information, by not generating that part of the code (or at least not in the same component), you may just be able to make it feasible. The thing to keep in mind is that combining metadata sources makes things more complicated, so try and keep them seperated.

I hope this article helps you out with your choices in wether or not to generate specific parts of your application code. If you have any questions, remarks, etc. you know the drill.

Tuesday, July 28, 2009

Adventures while building a Silverlight Enterprise application part #17

Today we are looking into databinding to the ComboBox.SelectedItem property trough a custom dependency property in a UserControl.

Post 42
But before all that I want to let you all know, this is post #42 on Developers 42. For obvious reasons this is a special post on my blog. As I started out last year, I didn't have any visitors, but now I average about 1700 visits a month. A large part of these visits come trough Google, but a special thanks goes out to Dave Campbell for publishing a lot of my articles on SilverlightCream.com. Trough his great efforts of bringing us the latest and greatest on Silverlight, his website is the second greatest referrer, only topped by Google. I won't elaborate any more on this. Stats, highs and lows will all be published in October when the blog celebrates it's first year of existence.

Binding to ComboBox.SelectedItem trough a custom dependency property in a UserControl.
I ran into this building a user control based on the requirement that we need a combo box that includes an edit button next to it when needed and also provides a label when needed. Simplest way to do this (at least as I see it), is trough building two UserControls. The first combines the ComboBox with a Button and the second combines the result with a TextBlock. Today we want to focus on the first one, which I dubbed ExtendedComboBox. I wrote the following XAML as a start:

<UserControl xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input"
xmlns:inputToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
x:Class="ExtendedComboBox.ExtendedComboBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
x:Name="extendedComboBoxControl"
>
<StackPanel x:Name="stackPanel" Orientation="Horizontal" HorizontalAlignment="Stretch">
<ComboBox x:Name="comboBox"
HorizontalAlignment="Stretch"
SelectionChanged="comboBox_SelectionChanged"
>
</ComboBox>
<Button x:Name="editButton" Content="..." Padding="5,0,5,0" LayoutUpdated="editButton_LayoutUpdated"
Click="editButton_Click"/>
</StackPanel>
</UserControl>


Simple enough. All I had to do now was add some dependency properties to control some functionality and Bob's your uncle, wright? Wrong! I will spare you the details on sizing specifics and events, as this is not the focus of this article.

For databinding I figured I would need to bind to the ItemsSource and the SelectedItem properties of the ComboBox. Here is the code I initially came up with:

publicIEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set
{
SetValue(ItemsSourceProperty, value);
comboBox.ItemsSource = value;
}
}

// Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc...
publicstaticreadonlyDependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(ExtendedComboBox), newPropertyMetadata(null));

publicobject SelectedItem
{
get { return (object)GetValue(SelectedItemProperty); }
set
{
SetValue(SelectedItemProperty, value);
comboBox.SelectedItem = SelectedItem;
}
}

// Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc...
publicstaticreadonlyDependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(ExtendedComboBox), newPropertyMetadata(null));


As you can see these are standard dependency properties, only I've added a line to assign their values trough to the ComboBox. For the ItemsSource property this works like a charm, however, for the SelectedItem property it doesn't.

After struggling with this, building a complete test rig and reading trough books worth of blog posts, I finally came up with the following solution. I removed the passing trough of the value in the properties setter method and added manual binding for the property in the constructor of the ExtendedCombobox. Here is my new constructor:

public ExtendedComboBox()
{
InitializeComponent();
Binding selectedItemBinding = newBinding("SelectedItem");
selectedItemBinding.Source = this;
selectedItemBinding.Mode = BindingMode.TwoWay;
comboBox.SetBinding(ComboBox.SelectedItemProperty, selectedItemBinding);
}

This way the ExtendedComboBox becomes the source of the binding for the ComboBox.SelectedItem property. After adding this (and obviously also implementing the Equals and GetHashCode methods on the business objects involved) it now works like a charm, without having to write any extra code in the modules that use this control.

Please leave me a comment if you have any questions, remarks or if you just want to say hi.

Wednesday, July 15, 2009

CodeEmbed4Web Beta 1 Release

Today it is my pleasure to announce to you the release of CodeEmbed4Web Beta 1. This public beta release of my new tool is available for download below.

As written in earlier posts, this tool allows you to copy code from Microsoft Visual Studio or another program that copies it's code in Rich Text Format, convert that code to other formats using predefined templates and then paste that converted code into any other program. The purpose of this tool is to quickly convert source code into publishable formats, like for example HTML, with a minimal effort and without limitation as to where it's going to be used.

With Beta 1, two templates are included:

  • CodeEmbed4WebXml.xslt allows you to get an exact copy of the XML generated by the tool. This enables you to build your own .xslt templates based on example XML files you can generate yourself.
  • ToHtml.xslt allows you to directly convert any code to html, so you can copy it into an html compatible program.
Feel free to add your own templates in the templates folder you find in the installation folder. New templates are automatically added to the tool as it starts up. If the tool is already started, please click the Refresh button that is below the list of templates.
The template you had selected last, will be selected when the tool starts.

Now without further delay, I present you with the download link:

CodeEmbed4Web Beta 1 (.msi)

If you need any support, found a bug, ran into an error, have any questions, suggestions or remarks, or you just want to let me know you are using CodeEmbed4Web Beta 1, please send an email to codeembed4web@gmail.com.

Update: Unfortunately I have recieved some reports of CodeEmbed4Web not being able to start. For some reason it throws an exception. I have been able to reproduce this behavior and I am looking into it. As soon as I figure it out, I will let you know. If you have this problem and if you are willing to provide me with some information on this, please send an email to codeembed4web@gmail.com.

Update: I've recently fixed the above issue and reposted the setup at the above link. I'll also release a simple patch soon.

I hope you all enjoy this tool and please provide me with feedback.

Friday, July 3, 2009

The birth of CodeEmbed4Web part #2

As it's Friday today, I figured I give an update on the CodeEmbed4Web project. I've been working on this on and off for the past week and a half and got some stuff done. As you may still remember from the previous post I sad I would test the mechanism I came up with to make sure it works with XAML as well. I'm happy to let you know it works exactly like expected.

I haven't got around to building a template for C# yet, let alone for XAML, but I have been putting a lot of thought into how the user interface for this tool should look. Some considerations:
  • The tool shouldn't be invasive. This means that it should take the smallest space possible without disturbing the functionality.
  • As I'm using WPF, I figured it should look good, but as I'm not much of a designer I figured I would use one of the themes from the WPF Toolkit.
  • It should be flexible in allowing to add new templates.

After playing around with Microsoft Expression Blend 3 Preview I came up with what you can see in the screenshot below.




No, it's not integrated with Visual Studio. That's just to show you how small the user interface is. You can go trough the buttons from top to button, to use the tool. The top tool expands a list of templates, so you can select your template. The middle button converts whatever code is on the clipboard and puts it back on the clipboard. The bottom button expands a menu which, at the moment, only allows you to close the tool.

At the top of the user interface, above the first button, is a handle you can use to drag the tool anywhere.

So, next steps:

  1. Finish up the user interface in terms of behaviour (not showing it in the task bar and staying on top of other windows, just to name a few).
  2. Build a template for C#
  3. Build a setup
  4. Release Beta 1

I would love to know what you think about the user interface and if you have any ideas to further improve on it. Please let me know what you think, by leaving me a comment.

Monday, June 29, 2009

Adventures while building a Silverlight Enterprise application part #14

As some of you may remember from the very first episodes of this series, in our application we use modules to separate functionality. This allows for a scalable solution on many fronts. Recently however I was asked by some of the functional designers if it was possible to use the modules in multiple ways.
Now this always was the plan, but some of the requirements were missed in the earlier stages of our project. We didn't anticipate the fact that, not only would our modules have a different look, based on where they would be used, also they would have to have some features change, based on the fact that they were used differently.
Here is what we have identified we need:
  • Normal use: this is basically how we have our modules in our applications. They should display there titles on the top, provide sizing capabilities for either two or three formats (title bar only, normal view and extended view for datagrid modules), provide a save button (and a new button for our datagrid) and some other functionality.
  • Wizard use: we want to stack some modules on top of each other in different steps of wizards we provide for our users. This means the title bar should be gone, the new and save buttons are not there, modules can't size and there should be a title on the left with a description for each module.
  • Popup use: we want some modules to be able to pop up and be modal to all other parts of the UI. The exact requirements are to be determined.
  • Separate use: we want to be able to use some modules as a standalone peace of kit. Again we're not completely sure as to what the requirements will be.
I pondered about this for a bit and then said, "sure we can do this, just give me a day". Here is what I came up with. I decided that each module should not provide any of the functionality that has to change between uses. These functionalities should be provided by a container. I could then build a container for each use of a module. This allows me to not only provide XAML code in the container (which, as you all know from a previous post is not possible in base classes for user controls). It would also give me a single point to change these shared functionalities, which took away another conceirn about not being able to implement changes to the general functionality of a module without touching each module.

I went ahead and put this in our application and I was pleased by the fact that it was so easy to do this in Silverlight. I simply have a usercontrol with the functionality and XAML required and all I needed to embed a module was a ContentPresentor and to have some interface (IModule) to provide access to some of the functionality inside the module (like save and new).

I would love to show you some code, but I can't as this is part of my companies software. Still I hope this inspires anyone that needs to have a single point to put code, but still needs to be able to place XAML as part of that, to consider using a container type of solution with the ContentPresentor. If you have any questions, comments or other responses, please wait for the beep...

Beep! :-)

Wednesday, June 24, 2009

The birth of CodeEmbed4Web

I've been blogging here for some time now and I've been active on many forums and in several communities and I've always been annoyed by the fact that non of the media used has decent support for adding different kinds of source code and other technical content to them. Sure, a there are a lot of suggestions as how to do this, but they never really met my expectations. They either take to much effort or the result is not looking good enough.

Thinking about this the other day made me decide to make my own tool for this. I sad down, thought about my process of using technical content and I came up with how I felt the flow should be. Here is what I figured will work the best for me:
  1. Copy some code from Visual Studio
  2. Click a button in my tool / press some short-cut key combination
  3. Paste the result in whatever
Using these steps would have the least impact on my normal working flow and therefor make the most sense. There are some challenges, however. I would need the tool to detect whatever I put in to it and I would need it to know what format to convert it into. Especially that last step seems to be impossible. How would it know what I'm planning to paste my code into?
Thinking about that some more, I decided to scrap that last bit and add a small step to the flow:
  1. Copy some code from Visual Studio
  2. Choose a target if necessary
  3. Click a button in my tool / press some short-cut key combination
  4. Paste the result in whatever
Obviously I can still optimize that by making available more buttons or short-cut key combinations, but I didn't want to put in that much effort right at the beginning.

As I'm experienced in buildin Silverlight 2.0 applications I decided to use WPF as my technology. This allows me to access the clipboard and it has better keyboard support then Silverlight. Also, having to open a web application, has been one of the causes that using some of the existing tools takes to much effort.

I've been playing around with WPF and the clipboard and found out that VS (at least 2008) copies it's content to the clipboard using the RTF format. This drew me towards the RichTextBox control, so I placed one in my window and pasted the content into it and it looked great. I studied the documentation on the underlying FlowDocument technology and decided to run with it.

Now I've already built code to convert RTF to a FlowDocument instance (without the RichTextBox control, obviously) and then to XML, which will allow me to build several XSLT templates on top of that XML, which I can then apply to the XML to get to the end result.

Next steps will be:
  1. Test this with XAML
  2. Build templates for C# and XAML to convert to HTML (and maybe XAML?)
  3. Brush up the user interface
  4. Build a setup
  5. Release Beta 1
You've read that right. I will release this tool, and for free (at least for now). So if you're interested in this tool, please come back to my blog for more news or better yet, subscribe to my RSS feed on the top-right of this page.
If you have any question, suggestions or comments, you know the drill (that means, leave them below).

Wednesday, June 10, 2009

Adventures while building a Silverlight Enterprise application part #12

In this episode we have a closer look at the behavior of the Silverlight 2 DataGrid and especially when databinding and in relation to selecting items.

One of the UI elements that we have in our application is that whenever you select an item in DataGrid A, this updates DataGrid B. Not a very difficult peace of code on itself. However, if you need to select an item from DataGrid B right after this update, that's where trouble begins.
Debugging my source I realized that it had to do with the timing between setting the ItemsSource property to supply new data, and setting the SelectedItem property to select the correct item.
DataGrid A is only a UI element that happens to trigger the refreshing of the data, so it's not important in our problem.

With this information I wrote a small testapplication that demonstrates the problem I had.
The XAML looks like this:

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="DataGridSelection.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300" Loaded="UserControl_Loaded">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<data:DataGrid x:Name="dataGrid"
SelectionChanged="dataGrid_SelectionChanged"
ItemsSource="{Binding}"
LoadingRow="dataGrid_LoadingRow"/>
<Button x:Name="updateItemsSourceButton"
Content="Update ItemsSource"
Click="updateItemsSourceButton_Click"
Grid.Row="1"/>
</Grid>
</UserControl>

As you can see I have a single DataGrid to place data in. I subscribed to the SelectionChanged and LoadingRow events so I can demonstrate what happens.
I also use a Button that allows me to refresh the data easily and finally I have a Loaded event to handle the initial data creation.

Next is the code behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading;

namespace DataGridSelection
{
public partial class Page : UserControl
{
private ObservableCollection<string> _data;
private bool _loadingRow;

public Page()
{
InitializeComponent();
RecreateData();
}

private void RecreateData()
{
_data = new ObservableCollection<string>();
_data.Add("Item 1");
_data.Add("Item 2");
}

private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Debug.WriteLine("Selection changed to index {0}", dataGrid.SelectedIndex);
if (_loadingRow)
{
Debug.WriteLine("Changed because of loading row");
}
_loadingRow = false;
}

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
dataGrid.ItemsSource = _data;
}

private void updateItemsSourceButton_Click(object sender, RoutedEventArgs e)
{
int selectedIndex = dataGrid.SelectedIndex;
RecreateData();

dataGrid.ItemsSource = _data;
dataGrid.SelectedIndex = selectedIndex;
Debug.WriteLine("Exiting click event");
}

private void dataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
Debug.WriteLine("Loading row");
_loadingRow = true;
}
}
}


So for test data I've simply used an ObservableCollection of strings, to which I add two items in the RecreateData method. This allows me to reinstantiate the collection at any given moment.

The problem code is in the Buttons Click event. I first retrieve the SelectedItem index, so I can later try and restore the selection. I then reinstantiate the data collection and reasign the data to the ItemsSource property of the DataGrid. After that I set the SelectedIndex property to restore the original selection. It seems like this should work, right? Wrong!

If you would test this, you'd find out that after reloading the data the first item is always selected. It doesn't matter what value I put in SelectedIndex. I could do exactly the same thing with SelectedItem and it would have the same result.
To make it more clear, as to what happens when, I added the debug output to the source, ran the application, selected the second item (SelectedIndex = 1) and pressed the button.

Here is the debug output:

Loading row
Loading row
Selection changed to index 0
Changed because of loading row
Selection changed to index 1
Selection changed to index 1
Exiting click event
Loading row
Loading row
Selection changed to index 0
Changed because of loading row

Now, the first four lines are from starting the application. The fifth line is from me, selecting the second item in the grid by clicking it. The two lines after that are from the last two lines of code of the click event, first setting the SelectedIndex property and then exiting the event. As you can see, the actual loading of the data happens after we exited the click event. As a result the selection is reset after that as well.

To find out more about this, and maybe find a way to get around this, I fired up Reflector and started digging around in the DataGrid's code. I found out that it uses the SetValue method of it's base class (DependencyObject), but I couldn't exactly find out why the data gets loaded after the user code is executed, nor did I find any indication as to how I could get around this behavior. My best guess so far is that at some point the control of loading the data is passed trough a Dispatcher instance and gets transfered out the main thread (which makes sense as you don't want your user to wait for this process).

I did find a solution direction in my test application however. The _loadingRow field actually gave me some inspiration as to how to solve this in my application.

I use two methods and two fields for this solution. To update the _loadingRow field I wrote a method SetLoadingRow so I have some point where I can handle changes in the field.
I also wrote another method called SelectItem, backed by a field to store the selected item, independent of the DataGrid. In the SelectItem method optionally I also set the SelectedItem property of the DataGrid.
In the SetLoadingRow method I only update the SelectedItem of the DataGrid if I was loading rows, but I'm now done (so the new value passed is false, but the current value is true) and if I have a selected item already and it's different from the selected item in the DataGrid.

SelectItem is called whenever I need to select an item from code. SetLoadingRow(true) is called whenever the LoadingRow event of the DataGrid is triggered and SetLoadingRow(false) is called at the end of the SelectionChanged event of the DataGrid.

This workes like a charm (altough I had some very specific other issues concerning state between different parts in my application, but I won't bother you with that :-) ).
I hope this can be helpful to you as well, even if only to know your not the only one struggling with this tricky side effect. If you have any questions or comments, please leave them below. I always look forward to them.