Thursday, 28 January 2010

Changing the text selection color in WPF

Short answer: you can't! The color of the text selection (not of the background) is given by an (internal) class System.Windows.Document.CaretElement, inheriting from Adorner. Here is the bit of crappy code that makes this impossible:

protected override void OnRender(DrawingContext drawingContext)
{
if (this._selectionGeometry != null)
{
Brush brush = new SolidColorBrush(SystemColors.HighlightColor);
brush.Opacity = 0.4;
brush.Freeze();
Pen pen = null;
drawingContext.DrawGeometry(brush, pen, this._selectionGeometry);
}
}

And you might be thinking that it is a simple template change issue and if you don't add the bloody caret to the template it will work. Wrong! The Caret element is instantiated via code in classes as TextSelection, as an implementation of the ITextSelection interface which only has a getter for the Caret property. The TextSelection class is instantiated in all the controls that support text selection as internal properties or fields. Yay!

So unless you recreate the entire selection functionality, you are stuck with the SystemColors.HighlightColor color for selection. As Dr. WPF himself says: "It is entirely impossible in the current .NET releases (3.0 & 3.5 beta). The control is hardcoded to use the system setting... it doesn't look at the control template at all."

Better luck in WPF 4.0... maybe.

Wednesday, 27 January 2010

Making WPF applications display as on a particular operating system

WPF is great for styling. They even included different default styles for each Windows operating system so that the controls look "native". So making an application look as if native to the operating system is not a problem. But how can one do the opposite: force the application to always display as if on a specific operating system?

The solution is to include the default theme for that OS in the resources of your application, window, user control, etc, so one can even style different parts for different operating systems, if need be.

Well, this is how you can make you application use the Vista/Windows7 Aero interface. In you App.xaml add an Application.Resources block and a ResourceDictionary with the source /PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml. If you have already a style in your application resources, add the resource dictionary in a ResourceDictionary.MergedDictionaries block. Like this:

<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="/PresentationFramework.Aero,
Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35,
ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml"
/>
<ResourceDictionary Source="/My.Namespace;component/Themes/MyApplication.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>


The operating system theme files that you can choose from are:
AssemblyTheme file
PresentationFramework.Aeroaero.normalcolor.xaml
PresentationFramework.Classicclassic.xaml
PresentationFramework.Lunaluna.homestead.xaml
PresentationFramework.Lunaluna.metallic.xaml
PresentationFramework.Lunaluna.normalcolor.xaml
PresentationFramework.Royaleroyale.normalcolor.xaml


Of course, the method of loading the theme might be through code, and so this can be used to programatically and dynamically change the theme:

protected override void OnStartup(StartupEventArgs e)
{
Uri themeUri = new Uri(myThemeUriString, UriKind.Relative);
ResourceDictionary theme = (ResourceDictionary)Application.LoadComponent(themeUri);
Resources.MergedDictionaries.Add(theme);
}
base.OnStartup(e);
}

Tuesday, 26 January 2010

Custom Control does not resize in Visual Studio designer

I was working on a small ASP.Net control that inherited from Button, so nothing special. I went into Visual Studio in design mode and I noticed that the control did not display any resize handles so I could only move the control, not resize it using the mouse.

After intensive Googling, trying custom ControlDesigner classes with AllowResize set to true and all other kinds of strange things, I realised that in the Render method I would write a style tag while in DesignMode before rendering the button. The method was described in a previous blog entry to fix the problem with CSS files with WebResource entries inside and PerformSubstitution.

It appears that Visual Studio, by default, only resizes the controls that render an HTML element that has size. A style tag does not! The solution was to add a div around the control (and the style block) while in DesignMode. The only problem was that the div is a block element, while the input of type button is an inline element. That means that two div elements would place themselves one under the other, not next to the other like two buttons would. So I fixed the problem by also adding a float style attribute and setting it to left.

Here is a small code sample:

protected override void Render(HtmlTextWriter writer)
{
if (DesignMode)
{
writer.AddStyleAttribute("float", "left");
writer.RenderBeginTag("div");
// this renders an embedded CSS file as a style block
writer.Write(this.RenderDesignTimeCss("MyButton.css"));
}
base.Render(writer);
if (DesignMode)
{
writer.RenderEndTag();
}
}

House of Chains by Steven Erikson

Book coverAnother great Malazan book, the fourth in the series, House of Chains starts with the personal history of Karsa, the Teblor, previously known to us as Shai'k's Toblakai guardian. His tale is both brutal and inspiring, as he evolves from a mindless brute to a ... well... slightly minded brute. At the end of the book there is another battle, like I have been already accustomed by previous reads, only it must be the weirdest one yet. You have to read it to believe it.

Since it started with the singular story of Karsa and because of the many characters that were both introduced, developed from the previous stories or simply clashing at the end, the book felt fragmented (like Raraku's warren :) ). That wasn't so bad, however it opened to many avenues that need to be closed in following books.

At this point it is obvious to me that the Malazan Book of the Fallen is not really a series, but a humongous single story with many interlocking threads and characters. Like chains dragging ghosts of books read, I feel the pressure to end the series so I will probably start hacking away at the fifth book this week.

Monday, 25 January 2010

WebResource and PerformSubstitution in Visual Studio 2008 design mode

I was trying to make a web control that would be completely styled by CSS rules. That was hard enough with the browsers all thinking differently about what I was saying, but then I had to also make it look decent in the Visual Studio 2008 designer.

You see, in order to use in the CSS rules (or in Javascript resources, for that matter) files that have been stored as embedded resources in the control assembly, a special construct that looks like <%=WebResource("complete.resource.name")%> is required.

The complete resource name is obtained by appending the path of the embedded resource inside the project to the namespace of the assembly. So if you have a namespace like MyNamespace.Controls and you have an image called image.gif in the Resources/Images folder in your project, the rule for a background image using it is background-image:url(<%=WebResource("MyNamespace.Controls.Resources.Images.Image.gif")%>);.

Also, in order to access the CSS file you need something like [assembly:
WebResource("MyNamespace.Controls.Resources.MyControl.css",
"text/css", PerformSubstitution = true)]
somewhere outside a class (I usually put them in AssemblyInfo.cs). Take notice of the PerformSubstitution = true part, that looks for WebResource constructs and interprets them.

Great! Only that PerformSubstitution is ignored in design mode in Visual Studio!!. The only solution to render the control correctly is to render the CSS file yourself and handle the WebResource tokens yourself. Here is a method to do just that:

private static readonly Regex sRegexWebResource =
new Regex(@"\<%\s*=\s*WebResource\(""(?<resourceName>.+?)""\)\s*%\>",
RegexOptions.ExplicitCapture | RegexOptions.Compiled);

public static string RenderDesignTimeCss2(Control control, string cssResource)
{
var type = control.GetType();
/*or a type in the assembly containing the CSS file*/


Assembly executingAssembly = type.Assembly;
var stream=executingAssembly.GetManifestResourceStream(cssResource);

string content;
using (stream)
{
StreamReader reader = new StreamReader(stream);
using (reader)
{
content = reader.ReadToEnd();
}
}
content = sRegexWebResource
.Replace(content,
new MatchEvaluator(m =>
{
return
control.GetWebResourceUrl(
m.Groups["resourceName"].Value);
}));
return string.Format("<style>{0}</style>", content);
}

All you have to do is then override the Render method of the control and add:

if (DesignMode) {
writer.Write(
RenderDesignTimeCss2(
this,"MyNamespace.Controls.Resources.MyControl.css"
);
}


Update:
It seems that rendering a style block before the control disables the resizing of the control in the Visual Studio designer. The problem and the solution are described here.

Friday, 22 January 2010

Polyphasic sleep - should I try it?

Actual picture of meMy friend Meaflux mentioned a strange concept called polyphasic sleep that would supposedly allow me to spend less time sleeping, thus maximizing my waking time. I usually love sleep, I can sleep half a day if you let me and I am very cranky when forcefully waken up... as in every day when going to work, doh! Also, I enjoy dreaming and even nightmares. Sure, I get scared and lose rest and there are probably underlying reasons for the horrors I experience at night sometimes, but they are cool! Better than any Hollywood horror, that's for sure. My brain's got budget :)

Anyway, as I get older I understand more and more the value of time, so a method that would give me an extra of 2 to 6 hours a day sounds magical and makes me reminisce of the good times of my childhood when I had time for anything! Just that instead of skipping school I would skip sleep. But does it work?

A quick Google shows some very favourable articles, including one called How to Hack your Brain and the one on Wikipedia, which is ridiculously short and undocumented. A further search reveals some strong criticism as well, such as this very long and seemingly documented article called Polyphasic Sleep: Facts and Myths. Then again, there are people that criticise the critic like in An attack on polyphasic sleep. Perhaps the most interesting information comes from blog comments from people who have tried it and either failed miserably or are extremely happy with it. Some warn about the importance of the sleep cycles that the polyphasic sleep skips over, like this Stage 4 Sleep Deprivation article.

Given the strongly conflicting evidence, my only option is to try it out, see what I get. At least if I suddenly stop writing the blog you know you should not try it and lives will be saved :) Ok, so let's summarise what this all is about, just in case you ignored all the links above.

Most people are monophasic sleepers, a fancy name for people who sleep once a day for about 8 hours (more or less, depending on how draconic your work schedule and responsibilities are). Many are biphasic, that means they sleep a little during the afternoon. This apparently is highly appreciated by "creative people", which I think means people that are self employed and doing well, so they can afford the nap. I know many retired people have a biphasic sleep cycle at least and probably children. Research shows that people normally feel they need to sleep most at around 2:00 and 14:00, which accounts for the sleepiness we feel after lunch. The mid day sleep is also called Siesta.

Now, poliphasic sleep means you reduce your sleep (which in the fancy terminology is called core sleep) and then compensate by having short sleep bursts of around 20 minutes of sleep at as fixed intervals as possible called naps. This supposedly "fixes" your brain with REM sleep, which is the first in the sleep lifecycle, however it is a contested theory. The only sure thing seems to come from an italian researcher called Claudio Stampi who did a lot of actual research and who clearly stated that sleeping many short naps is better than sleeping only once at the same number of hours of sleep. So in other words six 20 minutes naps are better than one 3 hour sleep.

Personally, I believe there is some truth to the method, as many people are actually using it, but with some caveats. Extreme versions like the Uberman (six naps a day, resulting in 2 hours of actual sleep) probably take their toll physiologically, even if they might work for the mental fitness. Also, probably some people are better suited than others for this type of customised sleep cycles. And, of course, it is difficult for a working man to actually find the place and time to nap during the afternoon, although I hear that it has become a fashion of sorts in some major world cities to go to Power nap places and sleep for 20 minutes in special chairs. No wonder New Yorkers are neurotic :) On a more serious yet paranoid note: what if this works and then employers make it mandatory? :-SS

So, in the interest of science, I will attempt this for a while, see if it works. My plan is to sleep 5 hours for the core, preferably from 1:00 to 6:00, then have two naps, one when I get back from work (haven't decided if before or after dinner, as there are people recommending not napping an hour after eating) and another close to 8:30 when I go to work. So far I have been doing it for three days, but it seems all this needs at least a few weeks of adjustment.

Now, with 5 hours and 40 minutes of sleep instead of 7 I only gain 1.33 hours a day, but that means an extra TV show, programming a small utility, reading a lot and maybe even writing... so wish me luck!

Update: I did try it, but I didn't get the support I needed from the wife, so I had to give it up. My experience was that, if you find the way to fall asleep in about 5 minutes, the method works. I didn't feel sleepy, quite the contrary, I felt energized, although that may be from the feeling of accomplishment that the thing actually works :) Besides, I only employed the method during the work week and slept as much as I needed in the weekend. I actually saved about 40 hours a month, which I could use for anything I wanted. If one works during that time, it means an increase in revenue to up to 25%. That's pretty neat.

Thursday, 21 January 2010

Overloading persisted inner properties in ASP.Net web controls

I have this ASP.Net web control that has a property that is persisted as an inner property and sets some custom style attributes. Then there is another control that inherits from the first one and overloads this custom style property with another having the same name and returning a different type. All this is done via the new operator

Now, while this is perfectly acceptable from the standpoint of Object Oriented Programming and it compiles without any issues, I get a compile error when I actually use the property and save it in the aspx code. That is a limitation of ASP.Net and I could find no way to circumventing other than changing the name of the property. This would also be the case if you have two public properties that have the same name only differently cased.

While this second situation I understand, the first is really stupid. I am specifying the type of the control so there should be no issues with an overloaded property. I guess it has something to do with the persistence mechanism, but still... Annoying.