Wednesday, December 29, 2010

TV series I have been watching - part 7

It is time for another exhaustive list of TV series I have been watching. Some are great, some are horrible, but the moral of the story is I just can't stop :) Here it goes:
  • Caprica - A spin-off from Battlestar Galactica, it showed a lot of promise, tackling the culture of the twelve colonies, issues like emergent AI and virtual life. However, it did not appeal to the public so it was cancelled. I am yet to see the last episodes from the series, but I expect the quality of the show to have plummeted long before the official news of the cancellation. When a network exec puts limits like "get me audience or die" people just lose interest in doing something and it quickly becomes a self-fulfilling prophecy.
  • Doctor Who - one wacky adventure after another, I still watch this British series. What it lacks in budget it compensates with weird plot lines and original writing. Quite refreshing.
  • Eureka - a silly sci-fi comedy, I would have expected it to die after a few seasons. Alas, people like easy, silly, pointless shows and only resent the ones that makes them think. Season 4 is expected to resume in July 2011.
  • House MD - I am kind of stuck watching this less and less medical series, because my wife likes it. I am bored by the plot, characters and almost everything in it except the occasional interesting medical fact. I hear season 8 might be the last.
  • Criminal Minds - some episodes are pretty stupid, others are brilliant. The exposure of the minds of serial killers through behavioural analysis is a great subject. Alas, they put too much focus on the procedure and too little on the actual principles behind the work of the FBI unit. Don't fret, though, a spin-off with Forest Whitaker as the lead of another crime fighting group. Unfortunately, the joint episode from Criminal Minds that shouls have presented the new characters was weak and the new team pathetic.
  • Southpark - this animation comedy series has its bad moments, but usually it is exceptionally funny and making fun of recent events.
  • Dexter - the show keeps holding strong, even if they kind of drifted from the perfect quality of the first seasons. I hear season 6 might be last, even if the fourth book in the Dexter series, Dexter is Delicious, is now available. Lucky for the TV series, they only got inspiration from the books which were not of such good quality as the show.
  • Big Love - interesting story about a mormon family trying to maintain their plurimarital beliefs in the face of adversity from goverment and other mormons alike. The 5th season is to start soon, but it is also the last. It kind of went bad from the third one, anyway.
  • Fringe - I am yet to watch the episodes from season 3. It is a pretty dumb show, so people like it. I am waiting for a period in which I have nothing to do in order to watch it.
  • True Blood - I like True Blood! It's not the vampires, but the feel of the backwater town that is plagued by all kinds of supernatural creatures. I think the show did great, but lately it kind of stuttered. Season 4 is to start somewhere in June
  • Californication - luckily, father Christmas brought us two preair episodes from season 4 which should have started next year. I still like the show, but it is a far cry from the greatness of the first season, during which I wanted to make a son and name him David Duchovny.
  • Breaking Bad - is it good anymore? The show started great and I did watch it religiously, but it does seem to get less and less interesting. It's a crystal meth male version of Weeds.
  • Secret Diary of a Call Girl - Billie Piper could not have been more perfect for this series. She was delicious from the first time I saw her in that silly video clip of hers. The show was sexy, interesting, and will continue with a fourth season, which is said to be last. Why, God, why?!
  • Entourage - this series is another television gem. It features the Hollywood adventures of a talented actor and his close childhood friends. The show managed to maintain a consistent positive feel for five or six seasons, which made it both great and original in this world of TV drama. The last seasons, though, went for a dark weird vibe and the eigth season will be both short and the last. A feature film is in the works, maybe, but it doesn't matter, since the original feel is pretty much destroyed.
  • Stargate Universe - Yeah, finally a Stargate show that takes itself seriously! Or so I thought. When the audience didn't like the dark and gritty atmosphere, the black wind of show cancellation made everybody not give a damn. The result is a half baked show, troubled by financing and screenwriting issues. Poor Robert Carlyle did a marvelous job, but a single good Scottish actor can't save a show from its evil masters. The second season of Stargate Universe will also be the last.
  • Torchwood - A Doctor Who spin-off, it took a big break after an attempted publicity stunt. Season 4 is to start next year. Fun series, but when you take Doctor Who, you Americanize it and then you make it even sillier, you are bound to miss somewhere.
  • The Sarah Jane Adventures - another Doctor Who spin-off, directed almost exclusively towards young kids. Of course, I watch it and enjoy it very much.
  • V - the original miniseries was not great, but that is no reason to make a stupid show like this. It is about aliens invading Earth via subterfuge and manipulation and the human resistance. It quickly turned into a involuntary parody of World War II movies with dumb Germans and smart Allies.
  • Men Of A Certain Age - suprisingly good and serious, it is about three middle aged guys and childhood friends living their lives. It is funny, but deep, with characters that feel real and jokes that really make you think and smile. Way to go, Ray Romano! Season 2 just started.
  • Weeds - the show just ended its sisth season. The seventh should be its last. Not even the babeliciousness of Mary-Louise Parker could save the last season, which was boring and kind of pointless. Started so well, though.
  • The Good Wife - it is a lawyer show, mostly directed towards women, but I like it. Characters are complex enough, the law cases feel real and the plot is interesting.
  • The Walking Dead - woohoo! Zombie series! Also made after comic books, so they can't fail too much. I like it, but since it focuses on the personal drama of the survivors and not the survival itself, and since the zombies are slow and ridiculous... meh! :)
  • Shattered - Canadian show starring Callum Keith Rennie, which you may know from Battlestar Galactica, it is about a cop with split personality disorder. Not very realistic, with a 70's feel to it, even if it is supposed to take place in the present, but I watch it nonetheless. I wonder if there will be a second season to it.
  • Haven - supposedly based on a Stephen King short story, it is basically a mashup between Fringe and Twin Peaks. It's worse than both, but it is easy to watch when you shut your brain down.
  • Rubicon - The wife watches this, I can't. It is like somebody accidentally dropped a bit of Lost in Nikita, but also removed the hot chicks.
  • Royal Pains - an easy medical slightly-comedy show. Started funny, now it's just boring. I will tell you when it's over.
  • Identity - British police drama that had some potential. The Brits cancelled it after it's first season, but the ABC network is said to want to make their own series.
  • Lost Girl - Canadian show again, this time a sort of supernatural thing with a hot bisexual chick that is also a succubus as the lead. Buffy like, nothing serious, but at least it's sexy.
  • Nikita - Nikita is now an American-Asian, still bad-ass and with Michael wrapped around her little finger. Pointless show, really.
  • No Ordinary Family - a family of super heroes! What could be cooler? I stopped watching it after the pilot episode.
  • Better with You - my attempt to watch something really easy with the girls, a show with background laughter and stuff, it's about three couples of different ages and their developped manierisms. Instead of actually analysing the causes and finding solutions, though, they just focus on the inevitability that all comedy American couples look and sound the same in their age group. Yuck!
  • Pioneer One - this is a show that is created by an independent studio (read: two guys in a garrage), freely distributed via Bittorrent (legally) and financed through donations. For 20000$ an episode, it is pretty cool. I donated some money since I really want this to work. Don't expect a master-piece, but I personally enjoy it and await the release of the third episode.


Phew, that's about all. But there are also the shows that I intend to watch! :) Here is the list:
  • Terra Nova - a show that is supposed to start in the fall of 2011. The synposis sounds kind of ridiculous, but hey, it's sci-fi!
  • Tilda - an HBO comedy about two blogger women journalists: Diane Keaton and Ellen Page. Both are annoying, but good actresses, and HBO does good shows. Let's see how it goes.
  • Criminal Minds: Suspect Behavior - I mentioned this show as the spin-off from Criminal Minds. I don't hold high hopes for it, though, based on the episode that presented the new team.
  • A Game of Thrones - I've read the books and they were great! I predict the show will be epic, since the books themselves were detailed, complex, with great story and a bit of fantasy as well. I can't wait for the show to start.
  • Falling Skies - aliens are attacking, again. I wonder if they started this show to finally bury V, which sucks. However, how much better can another show be when the plot is that an advanced technological race comes to Earth to occupy it. I mean, this dump?!


Ok, now it's over... or should I mention the anime series I am watching as well... how about the web series? Hmm... :)

Tuesday, December 28, 2010

The important quotes

I've noticed a nice feature on news sites: they take important quotes from their articles and highlight them in special boxes in their articles. Helps with the skimming of an article when you don't have the time to read it. I've added the same feature to my blog and I would like to know if you, my readers, find it useful as well.

Monday, December 27, 2010

The error of futurology

There are visionaries today that are capable of describing the future, as they see it. If it is close to the actual future, they get to be called futurologists. Of course, one will jump up and say that futurology has a definition and it is an art or a science that has nothing to do with vision, but I say that this is exactly what it is: guesswork. Guessing can be facilitated, however, by studying trends, staying current with new technology and thinking ahead on the needs that people have and will have in the future.

So how come no one is really good at it? How come people said in the past that by now we would get to Mars and have free energy and the likes? The reason is simple: because we can, but we won't! Just like people walking on the street and witnessing a robbery or a beating just stay and watch, but don't act, we are a world of diffuse responsibility. Nobody is responsible, everybody is to blame. But it's not true. I am responsibile, and you are; we make the future, we are the people, we are the ones that DO anything and everything.

So what is the error of futurology: they assume we would do what we can, when in truth we only do what we care. My New Year's resolution is to care, see where it takes me.

Wacky WebRequest exceptions and the solution

I will start with the errors. I was trying to access a site using a simple WebRequest.Create(url) method and a System.Configuration.ConfigurationErrorsException was thrown, with the message Error creating the Web Proxy specified in the 'system.net/defaultProxy' configuration section. That was weird, since I was doing it all from a WPF application and I had never had to modify the configuration for it to work. The exception had an even crazier inner exception: System.Runtime.InteropServices.SEHException External component has thrown an exception. Google failed to provide a satisfactory answer to any of the errors, although there were quite a few people having the same problem.

I proceeded in creating a system.net/defaultProxy section in the app.config. I changed the True values of the proxy element to False:

<system.net>
<defaultProxy>
<proxy
usesystemdefault = "False"
bypassonlocal = "False"
/>
</defaultProxy>
</system.net>


Voila! No more errors in Create... exceptions would be thrownm however, by the GetResponse() method later on. This time no configuration exception, only the weird SEHException with the oh so helpful ErrorCode -2147467259 (0x80004005) which means "Unspecified Error".

I tried different stuff like resetting IIS, trying to decompile .Net assemblies and see where the error comes from (all to no avail since the error comes from a native Windows component. In my desperation I issued a "netsh winsock reset" in the command line and then restarted the computer. Frankly, I don't know if the command did it or just the restart. The fact is, it just worked afterwards.

So, here is the first exception:
System.Configuration.ConfigurationErrorsException occurred
Message=Error creating the Web Proxy specified in the 'system.net/defaultProxy' configuration section.
Source=System
BareMessage=Error creating the Web Proxy specified in the 'system.net/defaultProxy' configuration section.
Line=0
StackTrace:
at System.Net.Configuration.DefaultProxySectionInternal.GetSection()
at System.Net.WebRequest.get_InternalDefaultWebProxy()
at System.Net.HttpWebRequest..ctor(Uri uri, ServicePoint servicePoint)
at System.Net.HttpRequestCreator.Create(Uri Uri)
at System.Net.WebRequest.Create(Uri requestUri, Boolean useUriBase)
at System.Net.WebRequest.Create(String requestUriString)
InnerException: System.Runtime.InteropServices.SEHException
Message=External component has thrown an exception.
Source=System
ErrorCode=-2147467259 (0x80004005)
StackTrace:
at System.Net.UnsafeNclNativeMethods.OSSOCK.WSASocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, IntPtr protocolInfo, UInt32 group, SocketConstructorFlags flags)
at System.Net.Sockets.Socket.InitializeSockets()
at System.Net.NetworkAddressChangePolled..ctor()
at System.Net.AutoWebProxyScriptEngine.AutoDetector.Initialize()
at System.Net.AutoWebProxyScriptEngine.AutoDetector.get_CurrentAutoDetector()
at System.Net.AutoWebProxyScriptEngine..ctor(WebProxy proxy, Boolean useRegistry)
at System.Net.WebProxy.UnsafeUpdateFromRegistry()
at System.Net.WebProxy..ctor(Boolean enableAutoproxy)
and here is the second:
System.Runtime.InteropServices.SEHException occurred
Message=External component has thrown an exception.
Source=System
ErrorCode=-2147467259
StackTrace:
at System.Net.UnsafeNclNativeMethods.OSSOCK.WSASocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, IntPtr protocolInfo, UInt32 group, SocketConstructorFlags flags)
at System.Net.Sockets.Socket.InitializeSockets()
at System.Net.IPAddress.InternalParse(String ipString, Boolean tryParse)
at System.Net.NetworkInformation.IpAddrString.ToIPAddressCollection()
at System.Net.NetworkInformation.SystemIPGlobalProperties.GetFixedInfo()
at System.Net.NetworkInformation.SystemIPGlobalProperties.get_FixedInfo()
at System.Net.NetworkInformation.SystemIPGlobalProperties.get_HostName()
at System.Net.NclUtilities.GuessWhetherHostIsLoopback(String host)
at System.Net.ServicePoint.get_ConnectionLimit()
at System.Net.ConnectionGroup..ctor(ServicePoint servicePoint, String connName)
at System.Net.ServicePoint.FindConnectionGroup(String connName, Boolean dontCreate)
at System.Net.ServicePoint.SubmitRequest(HttpWebRequest request, String connName)
at System.Net.HttpWebRequest.SubmitRequest(ServicePoint servicePoint)
at System.Net.HttpWebRequest.GetResponse()
.

The solution? Restart the computer. I wish I had a better, more informed answer, on why this happened, but I do not. I welcome any further explanation on the issue and I hope this helps people not waste a few hours like I did.

Sunday, December 26, 2010

Free legally downloadable movies, supported by donations

I've just finished watching episode two from the first season of Pioneer One, a sci-fi show made by amateurs, financed by donations and freely downloadable via Bittorrent. That is just fabulous! An episode is done with 20000$ and they need about 40000$ more to finish the last two episodes of the series.

I thought of this kind of system myself a year or so ago as I was observing that almost all movies and shows I watch are made by Americans, through gigantic media outlets that are only interested in profits and cancel any good show on the basis of money alone. I was wondering: where are the people that would be to TV what bloggers are to printed press? Of course, writing an article in a free public place like Blogger is a lot simpler than making a movie, but the idea is there. Mangakus do it all the time, in the US the comic book is back, why not TV shows?

The series is really good for the money that went into it. Except for some clueless actors that play very small parts, the people involved act decently and the atmosphere of the show is powerful and enticing. The dialogue is also strangely good, as I am used to clichees being sprouted in scenes of a certain type and when that doesn't happen, I have an eery feeling of unreality!

Pioneer One is not the only show like this. There is a network, called Vodo, with the motto: We love free! that helps distribute a lot of these Creative Commons licenced films and shows. I really want this to work. This gets the money from people interested to watch and gives it to the creators, rather than some vampire distribution network.

On that note, I would like to also talk about another TV show that is about to appear, called S.T.A.L.K.E.R. Yes, indeed, it is a TV series inspired by the game with the same name, which in turn was inspired by Roadside Picnic, by the Strugatsky brothers. The show is made by the Ukranian company that made the game and you can follow the progress of the series by going to its official site. The S.T.A.L.K.E.R. show would not be freely released, but at least it is not part of the official channels for TV distribution. The story itself sounds cool and the S.T.A.L.K.E.R. universe counts about 40 books already (in Russian, unfortunately, but give it time).

It moves slowly, but surely. I am convinced that in a few years people will make and distribute work via the Internet, directly sponsored by the people interested in their creation. All the salesmen in the middle will just be bypassed and creators will be controlling the cultural market rather than distributors. It only feels natural: if you distribute something under a Creative Commons licence, there can be no piracy :) So there, what I've always said comes true: the death of piracy is synonimous with the death of mammoth distribution companies and all their bullshit.

Tuesday, December 21, 2010

The Semicolon Wars - a very nice article about the cacophony of programming languages

Here is the link for the article, written by Brian Hayes, who argues that programmers should rather communicate peacefully, rather than fight each other over the language they are using. In the end it didn't really reveal anything grandieuse, but his post was detailed and funny and nice to read.

Update: I've thought about the article and I feel I have to add to this post.

First of all, I have to admit, as the author of the initial article admited that he is a Lisp fan, that I like the C-like structure of programs (minus the pointers :D). Actually, I would go so far as to occasionally dream of building an application which would convert Python and F# and Lisp and all those wacky languages into a semicolon/curly bracket version that I could use, then convert it back to their normal format before compilation or use. I agree with the author that the syntax itself is not very relevant to the language, but it is relevant to the users. I can "read" C#-like code much easier because by now I am fluent in C#. I believe that a nice option is to have the kind of functionality I am describing: something that would not change the language, but would slightly change the syntax so that someone can read it more easily.

Second of all, I am amazed that something that started as a nice introduction to an idea would continue with an admission (of guilt >:) ) that the author likes Lisp and then abruptly end. He didn't mention anything about the .Net idea which tries to unify a lot of programmaing languages under an intermediate compiler language. This brings the great opportunity to use a library written in a language with an application written in another. If that is not a good idea, I don't know what is!

Thursday, December 16, 2010

Programming Collective Intelligence by Toby Segaran

Book coverProgramming Collective Intelligence is easy to read, small but concise, and its only major flaw is the title; and that is because it is misleading. The book touches quite heavily on using collective information and social site APIs, but what it is really about is data mining. It may not be a flaw with the majority of readers, but personally I wouldn't care about the collective, the Facebook API or anything like that, but I was really interested in the different ways to analyse data. In that sense, this book can be taken as a reference guide on data mining.

Each algorithm and idea is accompanied by Python sources. I personally dislike Python as a language, but the author afirms he chose it intentionally because the algorithms look clear and the source is small, with its purpose unhindred by many language artefacts. The book was so interesting, though, that I plan (if I ever find the time :( ) to take all the examples and do them in C#, then place them on Github.

The book covers classification and feature extraction, supervised and unsupervised algorithms, filtering and discovery and it also has exercises at the end of each chapter. Here is a short list:
  • Making Recommendations - about the way one can use data from user preferences in order to create recommendations. Distance metrics and finding similar items to the ones we like or people with similar tastes.
  • Discovering Groups - about classifying data into different groups. Supervised and unsupervised methods are described, hierarchical clustering, dendograms, column clustering, K-Means clustering and diferent methods of visualisation.
  • Searching and Ranking - it basically explains step by step how to make a search engine. Word frequency, word distance, location of a document, counting methods, artifical neural networks, the Google PageRank algorithm, extraction of information from link text, and learning from user clicks can be found in this chapter.
  • Optimization - simulated annealing, hill climbing, genetic algorithms are described and exampled here. The chapter talks about optimizing problems like travel schedules and the example uses data from Kayak.
  • Document Filtering - a chapter about filtering documents based on preferences or getting rid of spam. You can find here Bayesian filtering and the Fisher method.
  • Decision Trees - a very interesting method of splitting information items into groups that have a hierarchical connection between them. The examples use the Zillow API
  • Bulding Price Models - k-Nearest neighbours, weighted neighbours, scaling.
  • Advanced Classification - Kernel Methods and Support Vector Machines. This is a great chapter and it show some pretty cool uses of data mining using the Facebook API
  • Finding Independent Features - reviews Bayesian classification and clustering, then proposes Non-Negative Matrix Factorisation, a method invented circa the late 90s, a powerful algorithm which uses matrix algebra to find features in a data set
  • Evolving Intelligence - bingo! Genetic Programming made easy. Really cool.
  • Algorithm Summary, Third Party Libraries and Mathematical Formulas - if you had any doubts you can use this book as a data mining reference book, the last three chapters eliminate them. An even more concise summary of the methods explained in the book, listing every math formula and obscure library used in the book


Conclusion: I really loved the book and I can hardly wait to take it apart with a computer in hand.

Collection Attached Properties with DataContext inheritance in WPF

The scenario is as follows: you want to attach a collection to an element and fill it via XAML. The objects that you add to the collection should inherit the element DataContext.

One issue arising is that if you use an attached property for a collection you cannot use a default value in the metadata (since it would be used for all the instances of the property) and that if you don't instantiate it, any attempt to add stuff to it via the markup will result in a collection null exception. If this were a mere dependency property from inside the control, the solution would have been to create the collection in the element constructor. Since it is an attached one, we don't have this mechanism available.

Another solution would be to instantiate it in the property getter, like a normal property with a backing field, but in the case of XAML, the dependency and attached properties are accessed directly via the DependencyObject.GetValue method, bypassing the parent class property getter entirely. The only solution to force going through the getter is to register the attached property with a name string that is different from the convention.

A quick example:

public static DependencyProperty MyAttachedCollectionProperty =
DependencyProperty.RegisterAttached("MyAttachedCollectionInternal",
typeof (ObservableCollection<MyItem>),
typeof (ParentClass),
new PropertyMetadata(null));


Above we are registering an attached property of type ObservableCollection<MyItem> ingeniously named MyAttachedCollection from a class named ParentClass. The convention says we whould register it using a name that is the DependencyProperty name without the ending "Property". I, however, have added an "Internal" string, which forces the property system to go through the getter!
Here is the getter:

public static void SetMyAttachedCollection(UIElement element, ObservableCollection<MyItem> value)
{
if (element != null)
{
element.SetValue(MyAttachedCollectionProperty, value);
}
}

public static ObservableCollection<MyItem> GetMyAttachedCollection(UIElement element)
{
ObservableCollection<MyItem> collection =
(ObservableCollection<MyItem>) element.GetValue(MyAttachedCollectionProperty);
if (collection == null)
{
collection = new ObservableCollection<MyItem>();
SetMyAttachedCollection(element, collection);
}
return collection;
}


Voila! This allows you to instantiate in the getter the troublesome collection.

Now, the other request in the scenario is to inherit the DataContext from the element the collection is attached to. To do that we at least need that the collection and the items in it to be DependencyObjects in order to have a DataContext, but we are going even further: we need to define them as Freezable! The Freezable abstract class requires you to implement a CreateInstanceCore method. Just make the MyItem class inherit Freezable and throw a NotImplementedException in the CreateInstanceCore method. For the collection itself, we need to inherit from another useful class: FreezableCollection<T>. After replacing ObservableCollection with FreezableCollection, the collection and the items have the same DataContext property as the element the property is attached to. An interesting fact here is that Freezable does NOT inherit from FrameworkElement, but it is a DependencyObject and the DataContext property does propagate down through the element tree.

One last interesting thing: the FreezableCollection class implements INotifyCollectionChanged, but explicitly! In order to use the CollectionChanged event you need to cast it in code to INotifyCollectionChanged.

Tuesday, December 07, 2010

Japanese music mix

It's been a while since I've last posted some music. This is not the kind of music I would listen to, mostly, but it is all Japanese music, 5 seconds of each band, a lot of bands. I thought it was a nice overview of a type of music I know almost nothing about. Enjoy!

Monday, December 06, 2010

A nice article about the vulnerabilities in the Internet openness

I found this link on the Codeproject newsletter, a place where I often find news that are not reported anywhere else and opinions that are well informed and interesting. So, here it is: The Weakest Link: What Wikileaks Has Taught Us About the Open Internet.

What it basically says is that the Internet is open only as the huge private companies that control it are willing to allow this openness. Governments and companies alike can pressure key points in order to control the spread of information. The laws (which set of laws, btw?) are vague, allowing a limbo in which only the powerful have the upper hand. Two services we take for granted, like DNS and the newly found fab cloud computing are easily attacked or pressured into blocking access or revealing information.

But what I found even more troubling is the way this challenge of Wikileaks (because what else can you call wearing the underpants of the biggest bully as your flag) has been answered so mindlessly by the US. The government that is trying to get its hands and make an example out of Gary McKinnon had his most secret documents openly exposed, making it look vulnerable, weak. Its response is nothing less than angry mindless rage: denial of service attacks on the Wikileaks DNS, harrassment of anybody supporting financially or technically the Wikileaks organization, very convenient rape charges against Julian Assange and so on. This is the behemoth that, behind nice faces like Obama's, does stuff like Guantanamo and has that huge inertia that would almost push humanity to extinction during the Cold War: "you mess with me, I mess with you".

However, this is a battle that any government has already lost. Short of a global appocalypse, the rabbit is out of the hat and the Wikileaks model will live on, regardless of who runs it and what structure it has. People have been shown to actually make a difference. All that media and movie onslaught of images of the evil government that can kill anybody at will and make everything dissappear has been proven a myth. They are not invulnerable. Even worse, they can't handle the stress, they are sore losers. They lost information, but also face and honor. And the funny thing is, they did it to themselves.

Friday, December 03, 2010

:visited CSS technique to get the browsing history of a visitor

I didn't know about this until today, but the technique itself is so simple that it must have worked on every browser from the first introduction of the :visited CSS selector. Think about it: in your site you have a css style that colors the visited links with a specific color. Then you place in your page a list of links to other sites (maybe in a hidden container). Using Javascript, you inquire the computed style for each of the links. Taadaa! You now know the links in your list that the visitor has recently visited.

You can download a PHP demo of the technique from here. Ain't this neat?

Update: I since found another interesting article, showing how a site could (on certain browsers that are not Internet Explorer >:) )see if you are logged on to another. Here is the link.

Thursday, December 02, 2010

You have nothing to fear if you have nothing to hide

Ok, so I had to say something about Julian Assange and Wikileaks. I will not speculate on the probably bogus rape arrest warrant for Assange (oh, it seems I did :) ), but instead focus on one of his quotes: "If governments would prefer to not have such information surface they have two choices: don't engage in wars that even their own military employees find reprehensible, and don't rely on secrecy as a method of governance.". Sounds like the old "Nothing to hide, nothing to fear" thing, used by so many people with power to justify their actions. Well, payback's a bitch, isn't it?

Looks like I am not the only one having this impression.

Wednesday, December 01, 2010

Cloning a WPF ControlTemplate

Before you go on, let me summarize this long post for you: while it is possible to clone a control template in order to change just some things in it, it is a difficult and error prone process. The code at the end of the post is a proof of concept thing, which works for simple scenarios, but needs additional work for complicated controls.

I was exploring the option of not overwriting the ControlTemplate of a WPF Control when I try adding stuff to it. Instead, I tried to get the ControlTemplate and manipulate it before putting it back. It is not as easy as it seems. Even more, people stack over each other to advise everybody not to do it. I am not saying it is an easy option, so my advice is to try other alternatives, if you have them, but the idea is: it can be done!

Let's take it step by step. In order to get the control template we should get it as soon as it is available, but perhaps before applying it. One could override OnApplyTemplate and do it there or, as it is my case (trying to do it via attached properties and lacking an ApplyingTemplate event), do it once when the control is initializing. The control template is easily obtained via the Template property. If you try to change anything in it, though, you will get an exception, because the template is sealed. So the only option is to clone it, change stuff in it, then set the control template to that clone.

The template is of type ControlTemplate, but it doesn't seem to contain much. It has Resources and Triggers properties, also a VisualTree property and a LoadContent method. There is also a Template property in the ControlTemplate class... try to set it and a null exception will be thrown, so forget it. The first two are easy to use, just iterate through the collections. VisualTree is of the weird and undocumented type FrameworkElementFactory, while LoadContent is a method that returns a DependencyObject.

Well, the idea is that LoadContent will return the content of the template which you should use to set the VisualTree property, but the process of getting a DependencyObject and getting a FrameworkElementFactory tree is not simple.

First things first: get a new ControlTemplate. Its contructor gets a Type parameter which we take from the TargetType property of the original template. We then add any resources from the original template to the resources of the new one. Next step is to take the content, using LoadContent, which will get us the first child of the element tree. In order to traverse it we will use the VisualTreeHelper static class which exposes the GetChildrenCount and GetChild methods.

The next step is to create a FrameworkElementFactory. It has a constructor which receives a Type and another which gets a Type and a name string. We will use the first, since the Name can be set afterwards. The type we get from the type of the DependencyObject returned by LoadContent. The VisualTree of the new control template will have to be this new factory object, but it also needs all the properties of the original object as well as all its children.

In order to get the dependency and attached properties of each element we will use the MarkupWriter.GetMarkupObjectFor method, which returns a MarkupObject. Each of its Properties will have a DependencyProperty property which will give us the properties. However, the value of the property is not so easy to get. If we use GetValue, any binding or markup extensions will be evaluated and probably give wrong results (since the control has not been initialized yet). Using ReadLocalValue brings us pretty close, only that for certain objects like Binding we don't get a BindingBase object, but a BindingExpressionBase. We need to cast the value we get to BindingExpressionBase and TemplateBindingExpression and get to the underlying binding object.

Now that we've got the properties and the correct values, we use the factory SetValue method to set it. A special case is Name which must be set directly to the Name property. We use AppendChild to add a factory to a parent factory.

The last step is to get the Triggers from the original template and copy it in the new one. Now Seal it and you have yourself a clone. Not sure how one would manipulate the template to get a usable and maintainable template manipulation, but this is how you start.

I know you are suckers for code, so here it is:

Update: Actually the collapsed code below doesn't work except for the simplest of templates. There are several reasons for it and I will explore them below.
Click to expand


The first problem I found was dependency properties registered as read only that could only be set from XAML, like VisualStateManager.VisualStateGroups. When trying to use the FrameworkElementFactory SetValue method it would throw an error. Funny enough, the only reason that happened is because said method is checking if the property is read only and throws an exception. I had to use reflection to circumvent this, and it worked, albeit really ugly.

The second problem was more basic. Not every property is a dependency property. Such a simple property is Grid.ColumnDefinitions! Not only it is not a dependency property, but it is also read only. So I had to find another mechanism to fix this. At this point you probably realise this method is not a good one to employ, but if you are really desperate (or stubborn, like me) there is a way. The solution I found is to save all the properties that I need to set into a list and then set them in a RoutedEventHandler invoked from the Loaded event!

And if this is not enough, simply setting the value from the template in the control doesn't always work. In the generated template control the ColumnDefinition objects are already in the ColumnDefinitionCollection of the control. Adding them to a control that the factory generates results in an error. What I did here is a simple value=XamlReader.Parse(XamlWriter.Save(value)).

In other cases, like the Border.Child property, it must be completely ignored! So a list of properties to be ignored is needed.

Conclusion: Some improvements have been done in the code, but it's a little larger than before. The complicated way in which this works makes it cumbersome to be used, and I would not recommend it, but it works and it has extension points where errors with properties can be handled. Here is the new code:
#region Using directives

using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

#endregion

namespace BestPractices
{
/// <summary>
/// Base class for ControlTemplate transforming classes
/// </summary>
public abstract class BaseTemplateTransformer : BaseControlTransformer
{
#region Public Methods

/// <summary>
/// Clones the ControlTemplate of a control and allows for its manipulation
/// </summary>
/// <param name="control"></param>
public override void Transform(Control control)
{
ControlTemplate template = control.Template;
if (template == null)
{
return;
}
// create new template
ControlTemplate newTemplate = new ControlTemplate(template.TargetType);
// copy the resources
foreach (object key in template.Resources.Keys)
{
newTemplate.Resources.Add(key, template.Resources[key]);
}
//get the VisualTree factory from the original template content
DependencyObject content = template.LoadContent();
newTemplate.VisualTree = OnGetElementFactory(content);
// copy the triggers
foreach (TriggerBase trigger in template.Triggers)
{
newTemplate.Triggers.Add(trigger);
}
// allow for template manipulation
OnBeforeSeal(newTemplate);
// seal the template and set it back
newTemplate.Seal();
control.Template = newTemplate;
}

/// <summary>
/// Creates a custom ControlTransformFactory for the content object.
/// Override in order to replace elements in the initial template.
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public virtual ControlTransformFactory OnGetElementFactory(DependencyObject content)
{
if (content == null)
{
return null;
}
// use the object type
ControlTransformFactory factory = new ControlTransformFactory(content, this);
return factory;
}

/// <summary>
/// Returns a safe value for setting on the control
/// </summary>
/// <param name="item">The value from the template</param>
/// <returns></returns>
public virtual object GetSafeValue(object item)
{
return getSafeValue((dynamic) item);
}

/// <summary>
/// Returns true if a property needs to be saved and set when the control loads.
/// Defaults to false, except for ColumnDefinitions and RowDefinitions
/// </summary>
/// <param name="propertyDescriptor"></param>
/// <returns></returns>
public virtual bool MustSetProperty(PropertyDescriptor propertyDescriptor)
{
return sMustSetProperties.Contains(propertyDescriptor.Name);
}

#endregion

#region Protected Methods

/// <summary>
/// Allows for the manipulation of a control template
/// </summary>
/// <param name="newTemplate"></param>
protected virtual void OnBeforeSeal(ControlTemplate newTemplate)
{
}

#endregion

#region Statics

private static readonly List<string> sMustSetProperties = new List<string>
{
"ColumnDefinitions",
"RowDefinitions"
};

/// <summary>
/// Transforms a DependencyObject tree into a FrameworkElementFactory tree
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
public static ControlTransformFactory CreateElementFactory(DependencyObject content)
{
if (content == null)
{
return null;
}
// use the object type
ControlTransformFactory factory = new ControlTransformFactory(content);
return factory;
}

/// <summary>
/// default return the same value
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private static object getSafeValue(object value)
{
return value;
}

/// <summary>
/// try to clone ColumnDefinition objects
/// </summary>
/// <param name="columnDefinition"></param>
/// <returns></returns>
private static object getSafeValue(ColumnDefinition columnDefinition)
{
return clone(columnDefinition);
}

/// <summary>
/// try to clone RowDefinition objects
/// </summary>
/// <param name="rowDefinition"></param>
/// <returns></returns>
private static object getSafeValue(RowDefinition rowDefinition)
{
return clone(rowDefinition);
}

/// <summary>
/// Clones an item via Xaml write/parse
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
private static object clone(object element)
{
string str = XamlWriter.Save(element);
return XamlReader.Parse(str);
}

#endregion
}
}

#region Using directives

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using System.Windows.Markup.Primitives;
using System.Windows.Media;

#endregion

namespace BestPractices
{
/// <summary>
/// FrameworkElementFactory used in control template transformers
/// </summary>
public class ControlTransformFactory : FrameworkElementFactory
{
#region Nested

internal class NoTemplateTransformer : BaseTemplateTransformer
{
}

#endregion

#region Instance fields

private readonly BaseTemplateTransformer mTemplateTransformer;

private RoutedEventHandler mLoadHandler;
private List<MarkupProperty> mSimpleProperties;

#endregion

#region Properties

/// <summary>
/// List of non dependency properties that will be set when the control loads
/// </summary>
protected List<MarkupProperty> SimpleProperties
{
get
{
if (mSimpleProperties == null)
{
mSimpleProperties = new List<MarkupProperty>();
}
return mSimpleProperties;
}
}

#endregion

#region Constructors

public ControlTransformFactory(DependencyObject content,
BaseTemplateTransformer templateTransformer = null)
: base(content.GetType())
{
mTemplateTransformer = templateTransformer ?? new NoTemplateTransformer();
// set its name
string name = content.GetValue(FrameworkElement.NameProperty) as string;
if (!string.IsNullOrWhiteSpace(name))
{
Name = name;
}
// copy the properties
foreach (MarkupProperty propertyItem in getProperties(content))
{
SetProperty(propertyItem);
}
// do it recursively
int count = VisualTreeHelper.GetChildrenCount(content);
for (int i = 0; i < count; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(content, i);
AppendChild(mTemplateTransformer.OnGetElementFactory(child));
}
}

#endregion

#region Public Methods

/// <summary>
/// SetValue that uses reflection to force DependencyProperties that were registered as read only
/// </summary>
/// <param name="dependencyProperty"></param>
/// <param name="value"></param>
/// <param name="forceSetReadOnly"></param>
public void SetValue(DependencyProperty dependencyProperty, object value,
bool forceSetReadOnly = false)
{
if (!forceSetReadOnly)
{
base.SetValue(dependencyProperty, value);
}
else
{
forceSetValue(dependencyProperty, value);
}
}

/// <summary>
/// Sets a value from a MarkupProperty object.
/// Dependency properties will be set via SetValue and the others via a Loaded handler on the object
/// </summary>
/// <param name="propertyItem"></param>
public void SetProperty(MarkupProperty propertyItem)
{
DependencyProperty property = propertyItem.DependencyProperty;
if (property == null)
{
setSimpleProperty(propertyItem);
}
else
{
object value = propertyItem.Value;
if (value == DependencyProperty.UnsetValue)
{
return;
}
SetValue(property, value, property.ReadOnly);
}
}

#endregion

#region Private Methods

/// <summary>
/// Force set value in the factory, even if the property is ReadOnly
/// </summary>
/// <param name="dp"></param>
/// <param name="value"></param>
private void forceSetValue(DependencyProperty dp, object value)
{
object resourceKey = getResourceKey(value);
if (resourceKey == null)
{
updatePropertyValueList(dp, value is TemplateBindingExtension
? "TemplateBinding"
: "Set", value);
}
else
{
updatePropertyValueList(dp, "Resource", value);
}
}

/// <summary>
/// Invoke the private UpdatePropertyValueList on the factory
/// </summary>
/// <param name="dp"></param>
/// <param name="propertyValueTypeName"></param>
/// <param name="value"></param>
private void updatePropertyValueList(DependencyProperty dp,
string propertyValueTypeName, object value)
{
object propertyValueType = Enum.Parse(sPropertyValueTypeType, propertyValueTypeName);
sUpdatePropertyValueListProperty.Invoke(this, new[] {dp, propertyValueType, value});
}

/// <summary>
/// Set a property to have its value set at load time
/// </summary>
/// <param name="markupProperty"></param>
private void setSimpleProperty(MarkupProperty markupProperty)
{
if (markupProperty.PropertyDescriptor == null)
{
return;
}
if (!mTemplateTransformer.MustSetProperty(markupProperty.PropertyDescriptor))
{
return;
}
SimpleProperties.Add(markupProperty);
if (mLoadHandler == null)
{
mLoadHandler = new RoutedEventHandler(simplePropertyHandler);
AddHandler(FrameworkElement.LoadedEvent, mLoadHandler);
}
}

/// <summary>
/// Handler on the Loaded event of the control
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void simplePropertyHandler(object sender, RoutedEventArgs args)
{
foreach (MarkupProperty propertyItem in SimpleProperties)
{
PropertyDescriptor propertyDescriptor = propertyItem.PropertyDescriptor;
if (propertyDescriptor == null || propertyItem.Value == null)
{
continue;
}
if (propertyDescriptor.IsReadOnly)
{
IList list = propertyItem.Value as IList;
if (list != null)
{
IList destinationList = propertyDescriptor.GetValue(sender) as IList;
if (destinationList != null)
{
foreach (object item in list)
{
destinationList.Add(mTemplateTransformer.GetSafeValue(item));
}
}
else
{
//shouldn't happend
}
}
else
{
// what now?
}
}
else
{
propertyDescriptor.SetValue(sender, mTemplateTransformer.GetSafeValue(propertyItem.Value));
}
}
FrameworkElement element = (FrameworkElement) sender;
element.RemoveHandler(FrameworkElement.LoadedEvent, mLoadHandler);
}

#endregion

#region Statics

static ControlTransformFactory()
{
// Get the types and methods that will be used in Reflection scenarios
sUpdatePropertyValueListProperty =
typeof (FrameworkElementFactory).GetMethod("UpdatePropertyValueList",
BindingFlags.NonPublic | BindingFlags.Instance);
sPropertyValueTypeType =
typeof (FrameworkElementFactory).Assembly.GetType("System.Windows.PropertyValueType");
}

private static readonly MethodInfo sUpdatePropertyValueListProperty;
private static readonly Type sPropertyValueTypeType;

/// <summary>
/// get the properties set on a DependencyObject
/// </summary>
/// <param name="content"></param>
/// <returns></returns>
private static IEnumerable<MarkupProperty> getProperties(DependencyObject content)
{
MarkupObject markupObject = MarkupWriter.GetMarkupObjectFor(content);
return markupObject.Properties;
}

/// <summary>
/// Get the ResourceKey property from an object, if it exists
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
private static object getResourceKey(object target)
{
if (target == null)
{
return null;
}
Type type = target.GetType();
PropertyInfo property = type.GetProperty("ResourceKey");
if (property == null)
{
return null;
}
return property.GetValue(target, new object[] {});
}

#endregion
}
}