Search code examples
c#silverlight-4.0datagridhyperlinkrichtext

InvalidOperationException when DataGrid loses focus to a HyperLink


I am having exactly this problem in my Siverlight4 application:

Description There is an error when a datagrid lose focus to a hyperlink (part of a RichTextBox).

The exception details are:

{
System.InvalidOperationException: Reference is not a valid visual DependencyObject.
at System.Windows.Media.VisualTreeHelper.GetRelative(DependencyObject reference, RelativeKind relativeKind)
at System.Windows.Media.VisualTreeHelper.GetParent(DependencyObject reference)
at System.Windows.Controls.DataGrid.DataGrid_LostFocus(Object sender, RoutedEventArgs e)
at MS.Internal.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)
}

To reproduce this error put a DataGrid with some data, and a RichTextBox with at least one Hyperlink, the RichTextBox must have IsReadOnly="True" , and at runtime with the focus on the datagrid, click the hyperlink.

The bug is in the file DataGrid.xaml.cs, line 4782: DependencyObject parent = VisualTreeHelper.GetParent(focusedDependencyObject);

From: http://silverlight.codeplex.com/workitem/7696

The workaround seems to be to edit the Silverlight DLLs, which I'd rather not do.

EDIT: Looks like clicking anywhere throws this exception.

Any other ideas how I could work around this problem?


Solution

  • We have come up with a workaround now.

    As we are binding to the XALM string of the FlowDocument we have added a new property to the Model for the RichtTextBox to bind to. In that property we are manually removing the hyperlink info and replacing it with BOLD tags.

    public string BodyXamlWithOutHyperLink
            {
                get
                {
                    const string RegExPattern1 = @"<Hyperlink \S*"">";
                    const string RegExPattern2 = @"</Hyperlink>";
    
                    string body = this.BodyXaml;
    
                    if (string.IsNullOrEmpty(body))
                    {
                        return string.Empty;
                    }
    
                    Regex bodyRegEx = new Regex(RegExPattern1);
                    body = bodyRegEx.Replace(body, "<Bold>");
                    bodylRegEx = new Regex(RegExPattern2);
                    body= bodyRegEx.Replace(mail, "</Bold>");
    
                    return body;
                }
    
                set
                {
                   // can be ignored, we are read-only anyway
                }
            }