Friday, February 26, 2010

ASP.Net using both inner properties and default innner properties

This post should have been titled Have your cake and eat it, too, but people need to find it in Google.

First of all, a bit of theory.

Web controls in ASP.Net can persist their properties in markup in two ways: attributes and nested tags. The problem with attributes is that the type of the property may be complex and iself have properties.

ASP.Net does have a mechanism for specifying subproperties by using a hyphen to separate properties and their subproperties. For example the BackColor property of a row of a GridView can be specified as both BackColor="Red" in the RowStyle tag or as RowStyle-BackColor="Red" in the GridView tag. However, that way is pretty unreadable and cumbersome that is why using inner tags is sometimes necessary (and implemented by decorating the properties with [PersistenceMode(PersistenceMode.InnerProperty)]).

But using inner tags is not always possible! Imagine a control like Panel. Its contents are interpreted as controls that are supposed to be rendered, so an inner tag would just be rendered to the page and not interpreted. There is no way of making such a control (decorated in its class declaration with [ParseChildren(false)]) have inner properties, but one can use something like an ITemplate property so that the controls can be placed in a tag of their own.

Also, consider controls like the DropDownList, in which ListItems are placed directly in the control tag and it is assumed automatically that they are children of the Items collection. That is because the Items collection is marked as [PersistenceMode(PersistenceMode.InnerDefaultProperty)] which means all the children of the control are considered elements in the property. Adding an inner tag would raise an error, as it would not be a ListItem object.

Yet, there is a way! And finding it was like discovering the holly grail. I have only tested it on a ListControl, but it should work on templated controls as well.

Let's start with a class that inherits from ListControl, therefore it has the Items collection in it and adding a complex property to it. I will create a special class called InnerTagClass that has a Text property. The control that inherits from ListControl and which I will call BaseClass will have an InnerTag property of type InnerTagClass. The code would look like this:

public class BaseClass:ListControl
{
private InnerTagClass mInnerTag;

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[NotifyParentProperty(true)]
public virtual InnerTagClass InnerTag
{
get
{
if (mInnerTag==null)
{
mInnerTag=new InnerTagClass();
}
return mInnerTag;
}
set
{
mInnerTag = value;
}
}
}
Now go into the designer and modify the Text property of InnerTag. You will notice that it will be saved as a hyphen attribute, while adding items to the Items collection would render the list items as children in the BaseClass tag:

<local:BaseClass ID="BaseClass1" runat=server InnerTag-Text="Test">
<asp:ListItem>Test</asp:ListItem>
</local:BaseClass>
Now, an InnerDefaultProperty is still an InnerProperty. You can put the ListItem inside an Items tag and it will still work, and also you can add an InnerTag tag with a Text attribute and it will work as well! However, if you go into the designer and you change the Text for the InnerTag property you get the changed property as an attribute and the previous InnerTag tag, with the old value. That is not acceptable.

However, you can inherit from the BaseClass, override the Items and the InnerTag properties and change their persistence mode to InnerTag! Here is the code:

public class InheritedClass : BaseClass
{
[PersistenceMode(PersistenceMode.InnerProperty)]
public override System.Web.UI.WebControls.ListItemCollection Items
{
get
{
return base.Items;
}
}

[PersistenceMode(PersistenceMode.InnerProperty)]
public override InnerTagClass InnerTag
{
get
{
return base.InnerTag;
}
set
{
base.InnerTag = value;
}
}
}
Now editing in the designer will create the Items tag and add the list items to it and an InnerTag tag with a Text attribute! But when you type it in source view, you get intellisense for both the Items tag and the ListItem tag! Adding only list items to the control works just like an inner default property.

There is a catch, though, as adding list items as direct children of the InheritedClass tag will not allow you to change the values of Items or InnerTag from the designer. It will save the current items in an Items tag, create the InnerTag, but fail to remove the previous items and thus throw a designer error. Still, fixing that is as easy as switching to source view and removing the old items.

Another possible question would be if one could add both InnerDefaultProperty and InnerProperty as decoration to a property in a class, but the answer is no. An error of Duplicate 'PersistenceMode' attribute is thrown.

Also, it might be possible to be able to fix that via a specialised editor, but I think it would be too complicated by far.

So there you have it: a way to satisfy both the styles of source people (like myself) and designer people by using inheritance and persisting differently the base property and its override.

Wednesday, February 24, 2010

Multiple CSS classes on the same element

You have an HTML element with two or more classes in the class name, something like "class1 class2" (separated by space and not by comma as some sites wrongly suggest) and some of the rules in the two classes overlap. What is order in which rules are read and do they overwrite other rules that are already in place?

I made a test HTML and I noticed that the rules in class2 overwrote the ones in class1, but since I had asked the wrong question, I had the wrong answer. If I changed the class name to "class2 class1" the result was the same!

It appears that the rules in CSS classes that overlap are overwritten based on their order in the document and latest win, overwriting the previous. In other words, if class1 would be defined later than class2, then its properties would overwrite class2's. The order of classes in a class name is complete without relevance!

Monday, February 22, 2010

System.MissingMethodException in Visual Studio DesignMode

Well, there are a lot of reasons why you might get exceptions in the designer, but just in case you get one of these, that make no sense, and you open another Visual Studio with the same solution and you debug the other Visual Studio when entering design mode and you still don't get any meaningful result... shut down Visual Studio and restart it.

Persisting subproperties as attributes rather than inner tags

There are all these attributes that can be used to decorate properties and classes so that the Property Grid control knows to handle them. One of these attributes is PersistenceModeAttribute, which specifies how to persist the information in ASP.Net markup. More often than not, you need to persist a complex object with subproperties as an inner tag. In that case one uses [PersistenceMode(PersistenceMode.InnerProperty)]. For the possible values of the constructor parameter, just follow the link if interested.

The problem comes when you want to persist the properties as attributes, in the ASP.Net specific "flattened" syntax, using a hyphen to separate property from subproperty. (<Style Color="red"/> as an inner tag is the same as Style-Color="red" as an attribute). You want this because some controls interpret their inner content as controls to be placed in them, such as the Panel control. You cannot add a Style tag in it because it just gets rendered in the page. The solution is to not use PersistenceMode! Of course, you might say, that's obvious. But it is not when your property already has the PersistenceModeAttribute decorating it and you are desperately looking for a parameter that does what you want. There is no such parameter. Not decorating the property is a separate option and it is the default behavior.

Saturday, February 20, 2010

The Bonehunters by Steven Erikson

Book coverOh, man, what a book this is. Steven Erikson uses a pattern in his epic Malazan Book of the Fallen series, with books that are standalone(ish) and others that continue the humongous story arches started in previous (or, indeed, later) books. The Bonehunters was heralded like a separate story, however that cannot be said to be true in any way. Old characters, patterns that evoke old stories, as is the birth of the Bonehunters, reminiscent of the Bridgeburners, and the sheer number of new characters, races and even gods make this book more of a hinge rather than a singular pillar in the epic. The number of open ended threads and unexplained new characters paves the way for the next four books. I am already starting to fear for the ending of the series.

What the book is about is difficult if not impossible to explain. It starts with a military campaign of punishment against the remnants of the Seven Cities army, but it ends suddenly and quite strange. The leadership of the elder Tavore sister unites the Malazans and binds them to her, in truth becoming hers and not merely an imperial army. There are strange machinations and moves from all the gods one can imagine, most of them hidden and quite hard to understand. What is even harder to explain is the way the empress allies herself with Mallick Rel and Korbolo Dom and starts rumours that make the Malazan population hate the Wickans, in truth war heroes of impecable honor. The ending is explosive but in no way final, leading the path onwards in the story.

Thursday, February 18, 2010

CSS cellpadding and cellspacing

There is one spiny issue when trying to move a html source from inline to CSS styling and that is the parameters of the table: cellspacing and cellpadding in particular.

From my tests it appears that cellpadding is overwritten by the CSS styling (the first time I ever see an inline attribute being overridden by CSS), however cellspacing does not. In order to remove the default cellspacing, use border-collapse:collapse on the table.

In order to set the table cellspacing through CSS, use the border of the td elements. Unfortunately, it doesn't work with transparent color, so you must set it to the color of the background. No luck if the background is an image. Margin on the cells doesn't work. Who uses cell spacing, anyway? Non Internet Explorer browsers have a table property called border-spacing, but it only works for some DOCTYPEs even in other browsers, so it's not reliable.

To set the table cell padding through CSS, just use the padding property of the cells. As I said earlier, it overrides the cellpadding property of the table.

So, in order to set 5px cell spacing and 5px cell padding through CSS, use this:
 body {
background-color:white; /* use the same color for the border of cells */
}
table {
border-collapse:collapse; /* remove default cellspacing */
border-spacing:5px; /* it works on some browsers on some DOCTYPEs */
}
td {
padding:5px; /* cell padding */
border:5px solid white; /* cell spacing */
}


You should set the padding as a general rule for all the TDs on the page. CSS classes like
table.MyClass td { padding:1px }
will affect all cells in all child tables! The more general the CSS selector, the easier will be to avoid overwriting some of your normal settings. For example, the CSS rule above would override
.myTD { padding-right:3px; }
because it is more specific.

Monday, February 15, 2010

The access key underline and the focused elements visual style

I was testing this WPF application on different operating systems and I have noticed that on Windows 2003 the access key letters in labels were always shown as opposed to the other operating systems where only by pressing Alt you could see the shortcut keys.

Apparently unrelated, there was another difference between Windows 2003 and other operating systems: clicking on elements would show their focus styling, while on any other, one needed to navigate using the keyboard Tab. This until I noticed that pressing Alt made the focus style appear on controls that I had clicked on.

Yes, the two are related and are linked to an operating system option that apparently cannot be changed on an application level. In Windows XP go to en empty area of the desktop, click Properties, go to the Appearance tab and click on the Effects button. Both the behaviors described above can be enabled or disabled by unchecking or checking Hide underlined letters for keyboard navigation until I press the Alt key. Here is the Microsoft link with instructions on how to do it.

In WPF, removing the visual focus to a control is as simple as setting the FocusVisualStyle property to {x:Null}, however there doesn't seem to be a way to enable or disable access key underscore.

Others have noticed this behavior, and people have suggested using the WM_CHANGEUISTATE Message on the window to set this functionality, by setting/unsetting the UISF_HIDEFOCUS flag. I have not tried it, though.

One can also try to change the setting in the registry. It seems the key is HKEY_CURRENT_USER\Control Panel\Desktop\UserPreferencesMask and if you want to hide the key focus and the label underline until you press alt you should unset the flag 20H from the first byte in the key.

Saturday, February 13, 2010

MySql UNION associability

In simple words, it seems there is none. After doing a query like SELECT stuff FROM (SELECT * FROM Table1 UNION ALL SELECT * FROM Table2) x WHERE condition, where Table1 and Table2 are identical in signatures, I noticed that it took 30 seconds on a combined 1 million rows. So I thought I would try to move the condition on each of the UNIONed tables: SELECT stuff FROM (SELECT * FROM Table1 WHERE condition UNION ALL SELECT * FROM Table2 WHERE condition) and it took 2 seconds.

So it seems as the server performed the union on all the rows, perhaps moving them in a temporary table, then filtered on the condition.

Coming from the world of Microsoft Sql Server which carefully creates a query execution tree and routinely solves queries similar to there two in an identical and optimised fashion, I was a bit surprised. Then again, being a Linux MySQL, maybe it was just not compiled right or didn't have an obscure option set up or something like that. Anyway, I was dissapointed.

Thursday, February 11, 2010

Some music: Florence (and the Machine), Sia (Furler) and Marina (and the Diamonds)

I haven't posted a music entry in quite some time, but this will compensate. Here are three female singers and some very good songs:

Cosmic Love from Florence and the Machine. You might also want to listen to The Drumming Song



The Girl you Lost to Cocaine from Sia. You might also want to listen to Buttons, with a fun video.



Hollywood from Marina and the Diamonds. She is a very prolific song writer and I like many of her songs. Not to mention she has a voice I love and she's cute as well. You might also want to listen to Mowgli's Road

Tuesday, February 09, 2010

Internal error: internal WPF code tried to reactivate a BindingExpression that was already marked as detached.

I started my WPF application and I got this weird exception: Internal error: internal WPF code tried to reactivate a BindingExpression that was already marked as detached. At the time of this entry, googling for this yields about 3 results, only one saying something about how internal WPF errors are usually multithreaded exceptions and, if you have it, try to remove IsAsync="True".

Needless to say, I didn't have that. The StackTrace of the exception was showing me, kind of obliquely, that the error was coming from a binding, but not why. Luckily, I looked in the Visual Studio Output window while getting the error. And there it was! A completely different error, this time telling me what the problem was.

Incidently, the error was caused by a style that had a BasedOn="{x:Type Something}" property setting. I know it is supposed to work, but in this case, it didn't, and it needed the more conservative yet safer BasedOn="{StaticResource {x:Type Something}}".

The cause of the error is only a detail, though, as the lesson here is to always look in the Output window while debugging WPF applications, even if you have an exception thrown. The messages there are more verbose and are actually telling you what bindings do, not what internal code is executed.

Monday, February 08, 2010

Loading the Session from a known SessionID

There are cases when pages need to use the same session, even if they are started from different contexts. One example is when trying to open a new window from within a WebBrowser control, or maybe issues with the ReportViewer control, or even some browsers who choose to open frames and new windows on different threads, like FireFox did for me a while ago. One might even imagine a situation where two different browsers open the same site and you want to use the same session. You have a SessionID, you are on the same server, so you should be able to use the session you want!

Here is how you do it:

var sessionID=(string)Request.QueryString["SessionIdentifier"];
if (Request.Cookies["ASP.NET_SessionId"] == null
&& sessionID != null)
{
Request.Cookies.Add(new HttpCookie("ASP.NET_SessionId", sessionID);
}

This piece of code must be added in the Global.asax.cs file (create a Global.asax file for your web site if you don't have one) in the void Global_PostMapRequestHandler(object sender, EventArgs e) handler and the sessionID must be given in the URL parameter SessionIdentifier.

Unfortunately you can't do it anywhere else. I've seen attempts to abandon the session in page load or page init and then do this, but it doesn't work. Basically, this post describes a horrible hack that replaces the default cookie where ASP.Net saves the SessionID value just before it is read.

As it can be a security risk, you should also add some validation logic so that the session hijacking is done only on certain pages that are likely to be opened in different application threads.

Saturday, February 06, 2010

Midnight Tides by Steven Erikson

Book cover, not very well chosenThe fifth book in the Steven Erikson's Malazan Book of the Fallen series, Midnight Tides is separated by the previous four in location, characters and, I would say, quality. We are witness to a battle between a lost enclave of the Tiste Edur and a lost enclave of The First Empire. From the perspective of the Malazans (which have no involvement at all in this book) both peoples would have been seen as ignorant savages, their conflict merely a petty squabble. The only characters we can recognize are the Crippled God, who is indirectly manipulating things, and Trull Sengar. Trull is almost the main character in the story, explaining his tortured past, although little connects this story with his freeing from the fragment of the Shadow warren in the forth book.

The end, another convergence of characters and stories and gods and magical powers, only opens avenues for further development, rather than actually explaining things. There are some interesting parts to the story, mostly the description of the Letherii culture, so much alike the Western culture today, which Erikson is criticising at every opportunity. He has similar ideas in House of Chains, but he really lets himself free in this one.

Aside from that and from the history of Trull Sengar which is surely to have an impact in the next books, the story was not really that captivating compared to previous chapters in the saga, almost like it all was a prop to describe Trull's way of thinking and to berate capitalism; like one of those TV show episodes that happen in the past so that we can understand what the character will do in the next episode that happens today. Still a good book, though.

Thursday, February 04, 2010

Tuesday, February 02, 2010

Checking if a WPF property is set or not

I had this scenario where a property was attached to objects but I wanted different default values for different objects. The code made it easy to just check if the property was set or not, then set the default myself. In order to do that, use the DependencyObject.ReadLocalValue instead of DependencyObject.GetValue and then check if the result equals DependencyProperty.UnsetValue. Like this:

return element.ReadLocalValue(MyProperty) == DependencyProperty.UnsetValue;
Of course, this can be used as an extension method for any element and/or property.

su: permission denied or the wheel of misfortune

I am not a Linux guru, but sometimes I need to use Linux systems and for that I use SSH. It is customary nowadays that one doesn't login remotely using the root account, but rather use another user, then use the command su (super user) to gain root priviledges. I've done it tens of times, most of the time checking if I can log in and then su with the new user.

Well, a few days ago I did not and, to my horror, I noticed that I couldn't use su from my new user, as a permission denied error message popped up. Plus, I had already locked the user I had previously logged in with. Add to this that the device in question had no keyboard/monitor jacks, it was remote, it only had a serial connection, my laptop did not and that the serial cable I tried to use with a borrowed desktop computer was not good enough for this damn device and you can understand the hell I was in.

Enough said, the idea is that some Linux distributions (like the ones based on BSD. Gentoo, for example) use what is known as the wheel group or the group that permits users to use su. Use usermod -G wheel myNewUser to add your user to the wheel group and always ALWAYS check if you have enough permissions for login users before you log off from root.