在 WPF 和 MVVM 中,如何将“复制”上下文菜单添加到 <Hyperlink>?

Con*_*ngo 3 c# wpf xaml mvvm mvvm-light

在大多数现代网络浏览器中,可以右键单击超链接并使用“复制链接地址...”上下文菜单。

在WPF中,我想知道是否有一种方法可以向<Hyperlink>XAML标记添加相同的功能?

我正在使用 MVVM Light。

Con*_*ngo 5

这实际上比应有的更困难。

原因是ContextMenu 不是可视化树的一部分,这意味着尝试使用任何最合乎逻辑的绑定都会返回 null 而不是预期值。

解决方案是将整个超链接包装在 UserControl 中,然后用于{Binding PlacementTarget.Content}访问我们想要的属性。在本例中,必需的属性是 URL,当我们想要通过上下文菜单将超链接复制到剪贴板时,我们需要该参数作为参数。当然,我们可以指定 URL 两次,但这违反了 DRY(不要重复)原则。

我正在使用MVVM Light

XAML

第二个的目的Command Parameter是绑定到NavigateUriHyperlink标记中的内容,并将其作为上下文菜单的参数传递,以便可以将其复制到剪贴板上。

<UserControl>
    <Hyperlink NavigateUri="http://www.google.com/" 
               Command="{Binding OnClickHyperlink}"
               CommandParameter="{Binding NavigateUri, RelativeSource={RelativeSource Self}}">
        www.google.com
        <Hyperlink.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Copy link address" 
                          Command="{Binding OnCopyHyperlink}"                                                  
                          CommandParameter="{Binding PlacementTarget.Content.NavigateUri, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}">
                </MenuItem>
            </ContextMenu>
        </Hyperlink.ContextMenu>
    </Hyperlink>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

C# 实现超链接点击

private ICommand _onClickHyperlink;
public ICommand OnClickHyperlink
{
    get
    {
        return _onClickHyperlink ?? (_onClickHyperlink = new RelayCommand<Uri>(
            hyperlink =>
            {
                // Handle Hyperlink click here using Process.Start().
            }));
    }
}
Run Code Online (Sandbox Code Playgroud)

C# 用于超链接复制

private ICommand _onCopyHyperlink;
public ICommand OnCopyHyperlink
{
    get
    {
        return _onCopyHyperlink ?? (_onCopyHyperlink = new RelayCommand<Uri>(
            hyperlink =>
            {
                Clipboard.SetText(hyperlink.OriginalString);
            }));
    }
}
Run Code Online (Sandbox Code Playgroud)