【问题标题】:Programmatically triggering the HyperlinkButton navigation以编程方式触发 HyperlinkBut​​ton 导航
【发布时间】:2012-03-16 08:40:36
【问题描述】:

我正在使用 Silverlight 3 HyperlinkButton,我想以编程方式触发通常在单击按钮时发生的导航。似乎没有支持这一点的公共方法。

OnClick 方法是受保护的,因此我可以从该控件继承以从自定义控件获取对该方法的访问权限,但有没有更好的方法来解决这个问题?

查看使用Reflector 的 OnClick 方法的实现并没有给我一个更好方法的明显提示,而且代码的复杂性让我想知道是否有充分的理由不允许以编程方式触发此事件.最低级别的托管代码调用是对MS.Internal.XcpImports.NavigateToSafeURINative 的调用,我在代码路径中看不到任何可以使用的公共方法。

【问题讨论】:

  • 这个问题在 SL4 中仍然存在(我怀疑是 SL5)。除了我之前描述的浏览器内解决方案之外,我已经更新了我的答案以包括浏览器外解决方案。

标签: silverlight navigation


【解决方案1】:

对于浏览器中的应用程序,HtmlWindow.Navigate 的作用如下,依靠唯一的目标名称来确保它在与托管 silverlight 应用程序的当前窗口不同的选项卡或窗口中打开。

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

对于浏览器外的应用程序,我发现的最佳解决方案是从HyperlinkButton 派生一个非常简单的自定义类并实现一个公共方法,该方法反过来调用受保护的OnClick 方法,如下所示。可以使用适当的 NavigateUri 和 TargetName 属性在 XAML 中声明此自定义类,就像基础 HyperlinkBut​​ton 一样。我希望通过反射调用 OnClick 方法来避免创建自定义类,但由于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();
        }
    }

【讨论】:

  • 请注意,这种技术可能会在当前的浏览器(IE8,9,Firefox 6..9)中被 Silverlight 4 阻止。仅使用 HyperlinkButtonNavigateUri(数据绑定)在我的情况下工作,而不是任何其他方法,包括命令。
  • 在 Silverlight 中使用 Chrome 或 IE 覆盖 OnClick 对我有用 :)
【解决方案2】:

您可以将按钮链接到命令,然后使用 Command.Execute() 从代码的任何位置触发命令。伪代码:

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>

代码(在 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);
    }
}

这在 MVVM 世界中特别有效。

【讨论】:

  • 我一定遗漏了什么,这对我调用受保护的 HyperLinkBut​​ton.OnClick 方法有何帮助?
  • OnClick 是您在代码隐藏中放入的代码实现,对吗?可以在 Command 委托中编写 OnClick 方法中的相同实现。
  • 很棒的答案,这帮助了我十倍。谢谢+1
  • 请注意,这种技术可能会在当前的浏览器(IE8,9,Firefox 6..9)和 Silverlight 4 中被阻止。仅使用 HyperlinkButtonNavigateUri(数据绑定)在我的情况下工作,而不是任何其他方法。 (我正在从另一个答案下方复制此评论)
  • @MarkCooper OnClick 方法包含执行导航的实现,我想要执行的正是这段代码。您可以订阅 Click 事件,在这种情况下,除了 OnClick 代码路径之外,还将调用您的代码隐藏实现,但这无助于触发 click 事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-20
  • 1970-01-01
  • 2019-04-04
  • 1970-01-01
相关资源
最近更新 更多