Martin Hollingsworth
Martin Hollingsworth

Reputation: 7339

Programmatically triggering the HyperlinkButton navigation

I'm using the Silverlight 3 HyperlinkButton and I want to programmatically trigger the navigation that normally occurs when the button is clicked. There does not appear to be a public method that supports this.

The OnClick method is protected so I could inherit from this control to gain access to this method from a custom control but is there a better way to go about this?

Looking at the implementation of the OnClick method using Reflector does not give me an obvious hint for a better way and the complexity of the code makes me wonder if there is a good reason for not allowing this event to be triggered programmatically. The lowest level managed code call is to MS.Internal.XcpImports.NavigateToSafeURINative and I don't see any public method in the code path that I could use.

Upvotes: 1

Views: 3039

Answers (2)

Martin Hollingsworth
Martin Hollingsworth

Reputation: 7339

For an in browser application, the HtmlWindow.Navigate does the trick as follows, relying on a unique target name to make sure it opens in a different tab or window to the current window hosting the silverlight application.

var hostingWindow = HtmlPage.Window;
hostingWindow.Navigate(siteHyperLinkbutton.NavigateUri, siteHyperLinkbutton.TargetName); 

For an out of browser application, the best solution I have found is to derive a very simple custom class from HyperlinkButton and implement a public method that in turn invokes the protected OnClick method as shown below. This custom class can be declared in XAML with the appropriate NavigateUri and TargetName properties, just like the base HyperlinkButton. I was hoping to avoid creating a custom class by invoking the OnClick method via reflection but this not possible due to the Silverlight Security Considerations for Reflection.

    public class CustomHyperlinkButton : HyperlinkButton
    {
        /// <summary>
        /// Exposes the base protected OnClick method as a public method.
        /// </summary>
        public void OnClickPublic()
        {
            OnClick();
        }
    }

Upvotes: 2

Mark Cooper
Mark Cooper

Reputation: 6894

You could link the button to a Command, then trigger the command anywhere from Code using Command.Execute(). Psuedo code:

XAML:

<UserControl x:Class="ClassName"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:commands="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation">
    <Button commands:Click.Command="{Binding MyCommand}" />
</UserControl>

CODE (behind or MVVM):

public class ClassName
{    
    ///Class constructor
    public ClassName()
    {        /// implement the command behaviour as a delegate
    MyCommand = new DelegateCommand<object>(
         delegate{ 
                 /// do your OnClick() behaviour implementation here 
                 }
        );
    }

    private DelegateCommand<object> _myCommand;
    public DelegateCommand<object> MyCommand
    {
        get { return _myCommand; }
        set { myCommand=value;
              OnPropertyChanged("MyCommand");}
     }

    /// Another method called from somewhere else in code
    void SomeOtherMethod()
    {
      MyCommand.Execute(null);
    }
}

This works particularly well in MVVM world.

Upvotes: 1

Related Questions