Thursday, November 3, 2011

WPF: Copying Hyperlink with command binding in Flowdocument / Richtextbox throw exception


Problem
In my product we use a  label containing flow document and there have a link to switch to another window. We can also edit the label and can be copied. For linking to other window we have used Hyperlink and switching is done by ICommand. Code is working well but when I tried to copy the hyperlink then it throw exception. When I tried to copy the it gives error as “'Command' to object of type 'System.Windows.Input.ICommand'. CommandConverter cannot convert from System.String”. That is because it is XAML parser is trying to serialize command into string string while I am trying to copy Hyperlink. But I only want to copy Hyperlink text not the command also. Those are known issues and mentioned in http://social.msdn.microsoft.com/Forums/ar/wpf/thread/0d117f34-3d5f-4596-86b3-cb3da78435d7  and http://stackoverflow.com/questions/3206258/commandconverter-valid-exception-or-net-bug and one solution is given with attached property http://eric.burke.name/dotnetmania/2007/07/08/23.05.00 . and there it has simulate command with hyperlink click event. But for that I need to introduce another class HyperlinkHelper and have to attach my command with HyperlinkHelper property.
My Solution :
My solution is very simple. I do not want command converter is not called while my command is going to be copy. As we know dynamic resource is deferred on demand  so the commandconverter is not called in this case while I am trying to copy that and it dynamically bind command when event is executed. So this is much easier solution than introducing another class  like Hyperlink helper.  and you have to do very simple thinks for the solution. First you need to create resource with that command so that when it try to resolve the resource command will be created.
  <DataTemplate.Resources>
            <XXXX:NavigationCommand x:Key="NavigationCommand" />
  </DataTemplate.Resources>




and while creating hyperlink you have to set it as dynamic resource.
<Hyperlink Command="{DynamicResource NavigationCommand}">Navigate</Hyperlink>




This resolve the problem of serialization problem of  commandconverter. And as it is dynamic resource XAML parser will not give error while trying to resolve as happen with StaticResource. It also solved my another problem of trying to resolve circular dependency {Cannot evaluate expression because the current thread is in a stack overflow state.}. and with lazy loading we have resolved this.