在WPF和MVVM中;复制“;上下文菜单到<;超链接>;
本文关键字:菜单 lt gt 超链接 上下文 WPF MVVM 复制 | 更新日期: 2023-09-27 18:28:04
在大多数现代web浏览器中,可以右键单击超链接并使用"复制链接地址…"上下文菜单。
在WPF中,我想知道是否有一种方法可以向<Hyperlink>
XAML标记添加相同的功能?
我正在使用MVVM Light。
这实际上比它应该做的更困难。
原因是ContextMenu不是可视化树的一部分,这意味着尝试使用任何最符合逻辑的绑定都会返回null,而不是预期值。
解决方案是将整个超链接封装在UserControl中,然后使用{Binding PlacementTarget.Content}
访问我们想要的属性。在这种情况下,所需的属性是URL,当我们想通过上下文菜单将超链接复制到剪贴板时,参数需要URL。当然,我们可以指定两次URL,但这违反了DRY(Dont Repeat Yourself)原则。
我正在使用MVVM Light。
XAML
第二个Command Parameter
的目的是绑定到父Hyperlink
标记中NavigateUri
的内容,并将其作为上下文菜单的参数传入,以便将其复制到剪贴板上。
<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>
C#用于超链接单击
private ICommand _onClickHyperlink;
public ICommand OnClickHyperlink
{
get
{
return _onClickHyperlink ?? (_onClickHyperlink = new RelayCommand<Uri>(
hyperlink =>
{
// Handle Hyperlink click here using Process.Start().
}));
}
}
C#用于超链接复制
private ICommand _onCopyHyperlink;
public ICommand OnCopyHyperlink
{
get
{
return _onCopyHyperlink ?? (_onCopyHyperlink = new RelayCommand<Uri>(
hyperlink =>
{
Clipboard.SetText(hyperlink.OriginalString);
}));
}
}
我发现以下方法在创建自定义日志窗口控件时很有用。它检查鼠标当前是否悬停在超链接对象内运行的文本上。
private void LogWindow_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
var hyperlink = (Mouse.DirectlyOver as Run)?.Parent as Hyperlink;
if(hyperlink != null)
{
//do whatever you want with the link now
//e.g. set the command param on a named menu item
MenuItem item = this.UriCopyMenuItem;
item.CommandParameter = hyperlink.NavigateUri;
item.Visibility = Visibility.Visible;
...
}
}