Wednesday 22 June 2011

The XAML Message From Hell: "Error HRESULT E_FAIL has been returned from a call to a COM component."

The most irritating thing in XAML-based projects (Silverlight, WPF) is the infamous "Error HRESULT E_FAIL has been returned from a call to a COM component."

Why Microsoft didn't decide to catch it and give a more appropriate exception escapes me. However, some things I've learned about this:

Your XAML is failing to load!


Now, your XAML may actually be correct, is the funny thing -- but maybe your project is missing the references. For example, I'm using the Silverlight Toolkit and setting styles at runtime on the fly, allowing for potential theming. I kept getting this error, even though my other projects which use the same code are building fine -- so why is my latest project failing to build?

I missed a reference that was used in the other project. When it came to load the XAML style, it was likely getting hung up on the missing reference and saying, "OK, I see you want to use System.Windows.Controls.Layout.Toolkit... but what in the world is that?"

To rectify this issue, it was necessary to add references all over again.

So, my troubleshooting advice is:


  1. Make sure the XAML is correct. When writing cross-platform (i.e. Silverlight and WPF), some of the controls/targets behave differently or have different properties. Visual Studio generally points this out as a build error.
  2. Make sure that you are referencing all dependent assemblies. Due to Silverlight's dependencies, if I write a library on top of Silverlight Toolkit, which then gets used in an application, that application needs to have the references to Silverlight Toolkit.

Good luck and when in doubt -- get an extra set of eyes!

Saturday 18 June 2011

Silverlight and WPF Measurement Pain

One of the more irritating things I've been dealing with in Silverlight and WPF is that sizing and automatic content placement is a pain. Don't get me wrong -- I love the new rendering engine and how it works to update the layout, but it can be a pain to "think in terms of WPF or Silverlight." Especially when the two don't exactly have the same methods of working.

I made a decision fairly early on to build a static Utilities class, which holds all of my ugly code where I have to use the very, very, very fun

#if SILVERLIGHT            

#else

#endif

constructs, which gets me to the point of this post.

It's difficult to determine the size of a control -- especially the size it wants to be. Ideally, yes, the DesiredSize will have that exact size. Unfortunately, the DesiredSize is somewhat misleading -- it's the DesiredSize of the space it's confined to. In addition, it works totally different between Silverlight and WPF.

I was primarily concerned with sizing things before they are rendered (they have no parent). This is drastically different from figuring out a size once they are in the layout tree and the control itself has a parent.

In any case, I'm only going to cover the basics. The most simple way to determine the size something wants to take up is to do artificially measure the element and then check the desired size. Assuming I have a TextBlock named Frank, the following code would determine the size Frank really wants:

Frank.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
Frank.Height = Frank.DesiredSize.Height;
Frank.Width = Frank.DesiredSize.Width;

Ah, a crafty trick (and it works in both Silverlight and WPF without a hitch; if Frank didn't have a parent, the code would be different between the two platforms). We make the control believe it has unlimited space, and then we can use DesiredSize. Play with it a little bit -- set a breakpoint on DesiredSize before and after this call and see the difference.

For more information about how the Layout system works (which is an excellent read for understanding how WPF/Silverlight work), check out this MSDN article: http://msdn.microsoft.com/en-us/library/ms745058.aspx

Wednesday 8 June 2011

Change logical and physical file names of SQL Server database

The easy way of renaming a SQL Server database is to open SQL Server Management Studio, select the database name on the tree on the left handside, hit F2 and type in the new name you want. It’s like renaming a file in a folder. But when you do that, the logical name and physical filenames of the database won’t change. In order to verify this, right click on the database name, select properties. Select Files sction on the left hand side. You can see the logical name and file name for data and log files on the right hand side.
Before attempting to change the names, you should take the database offline. You can do that using SQL Management Studio (right click the database and select Tasks > Take Offiline) or using the following SQL steatement.
ALTER DATABASE database_name SET OFFLINE
In order to change the logical name, execute the following T-SQL statement in a new query window for the database in SQL Server Management Studio. You can use the same statement for both data and log files by changing current_logical_name and new_logical_name.
ALTER DATABASE database_name MODIFY FILE (NAME=“current_logical_name”, NEWNAME=“new_logical_name”)
In order to change the physical file names, execute the following T-SQL statement. You can use the same statement for both data and log files by changing the logical_name and new_file_name.
ALTER DATABASE database name MODIFY FILE (NAME=“logical_name”, FILENAME=“C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\new_file_name_you_want.mdf”)
The data and log file location may change depending upon your SQL Server installation.
After executing the SQL statements and before bringing back the database online, go ahead and change the file names for data and log files (.mdf and .ldf) to new_file_name in the file system. Now you are good to go. Go ahead and bring the database online.
You can do that using SQL Management Studio (right click the database and select Tasks > Bring Online) or using the following SQL steatement.
ALTER DATABASE database_name SET ONLINE