上下文菜单
本文介绍将如何使用上下文菜单。
默认情况下, IBrowser
实例的上下文菜单是被抑制的。 如果 IBrowserView
实例是从没有自定义上下文菜单处理的 IBrowser 实例初始化的,则会注册默认上下文菜单处理程序。 默认上下文菜单中显示的项目取决于右键单击的网页项目,但是,在大多数情况下,它包含以下项目:”后退”、”前进”、”重新加载”、”打印”和”查看页面源代码”。
默认的上下文菜单实现是不能被修改的。 如果您需要添加或删除一些项目,您应该创建并注册自己的上下文菜单处理程序实现。
自定义上下文菜单
要构建自定义上下文菜单,应使用 IBrowser.ShowContextMenuHandler
处理程序。
WinForms
browser.ShowContextMenuHandler =
new AsyncHandler<ShowContextMenuParameters, ShowContextMenuResponse
>(ShowMenu);
browser.ShowContextMenuHandler =
New AsyncHandler(
Of ShowContextMenuParameters, ShowContextMenuResponse)(
AddressOf ShowMenu)
private ToolStripItem BuildMenuItem(string item, bool isEnabled,
EventHandler clickHandler)
{
ToolStripItem result = new ToolStripMenuItem
{
Text = item,
Enabled = isEnabled
};
result.Click += clickHandler;
return result;
}
private Task<ShowContextMenuResponse> ShowMenu(ShowContextMenuParameters parameters)
{
TaskCompletionSource<ShowContextMenuResponse> tcs =
new TaskCompletionSource<ShowContextMenuResponse>();
SpellCheckMenu spellCheckMenu = parameters.SpellCheckMenu;
if (spellCheckMenu != null)
{
BeginInvoke(new Action(() =>
{
ContextMenuStrip popupMenu = new ContextMenuStrip();
if(!string.IsNullOrEmpty(parameters.LinkText))
{
ToolStripItem buildMenuItem =
BuildMenuItem("Show the URL link", true,
(sender, args) =>
{
string linkURL = parameters.LinkUrl;
Console.WriteLine($"linkURL = {linkURL}");
MessageBox.Show(linkURL, "URL");
tcs.TrySetResult(ShowContextMenuResponse.Close());
});
popupMenu.Items.Add(buildMenuItem);
}
ToolStripItem reloadMenuItem =
BuildMenuItem("Reload", true,
(sender, args) =>
{
Console.WriteLine("Reload current web page");
browser.Navigation.Reload();
tcs.TrySetResult(ShowContextMenuResponse.Close());
});
popupMenu.Items.Add(reloadMenuItem);
// 当浏览器请求返回焦点时关闭上下文菜单。
EventHandler<FocusRequestedEventArgs> onFocusRequested = null;
onFocusRequested = (sender, args) =>
{
BeginInvoke((Action) (() => popupMenu.Close()));
parameters.Browser.FocusRequested -= onFocusRequested;
};
parameters.Browser.FocusRequested += onFocusRequested;
// 处理菜单关闭事件。
ToolStripDropDownClosedEventHandler menuOnClosed = null;
menuOnClosed = (sender, args) =>
{
bool itemNotClicked =
args.CloseReason != ToolStripDropDownCloseReason.ItemClicked;
if (itemNotClicked)
{
tcs.TrySetResult(ShowContextMenuResponse.Close());
}
popupMenu.Closed -= menuOnClosed;
};
popupMenu.Closed += menuOnClosed;
// 显示上下文菜单。
Point location = new Point(parameters.Location.X, parameters.Location.Y);
popupMenu.Show(this, location);
tcs.TrySetResult(ShowContextMenuResponse.Close());
}));
}
else
{
tcs.TrySetResult(ShowContextMenuResponse.Close());
}
return tcs.Task;
}
Private Function BuildMenuItem(item As String, isEnabled As Boolean,
clickHandler As EventHandler) As ToolStripItem
Dim result As ToolStripItem = New ToolStripMenuItem With {
.Text = item,
.Enabled = isEnabled
}
AddHandler result.Click, clickHandler
Return result
End Function
Private Function ShowMenu(parameters As ShowContextMenuParameters) _
As Task(Of ShowContextMenuResponse)
Dim tcs As New TaskCompletionSource(Of ShowContextMenuResponse)()
Dim spellCheckMenu As SpellCheckMenu = parameters.SpellCheckMenu
If spellCheckMenu IsNot Nothing Then
BeginInvoke(New Action(Sub()
Dim popupMenu As New ContextMenuStrip()
If Not String.IsNullOrEmpty(parameters.LinkText) Then
Dim menuItem As ToolStripItem =
BuildMenuItem("Show the URL link", True, Sub(sender, args)
Dim linkURL As String = parameters.LinkUrl
Console.WriteLine($"linkURL = {linkURL}")
MessageBox.Show(linkURL, "URL")
tcs.TrySetResult(ShowContextMenuResponse.Close())
End Sub)
popupMenu.Items.Add(menuItem)
End If
Dim reloadMenuItem As ToolStripItem =
BuildMenuItem("Reload", True, Sub(sender, args)
Console.WriteLine("Reload current web page")
browser.Navigation.Reload()
tcs.TrySetResult(ShowContextMenuResponse.Close())
End Sub)
popupMenu.Items.Add(reloadMenuItem)
' 当浏览器请求返回焦点时关闭上下文菜单。
Dim onFocusRequested As EventHandler(Of FocusRequestedEventArgs) = Nothing
onFocusRequested = Sub(sender, args)
BeginInvoke(CType(Sub() popupMenu.Close(), Action))
RemoveHandler parameters.Browser.FocusRequested, onFocusRequested
End Sub
AddHandler parameters.Browser.FocusRequested, onFocusRequested
' 处理菜单关闭事件。
Dim menuOnClosed As ToolStripDropDownClosedEventHandler = Nothing
menuOnClosed = Sub(sender, args)
Dim itemNotClicked As Boolean =
args.CloseReason <>
ToolStripDropDownCloseReason.ItemClicked
If itemNotClicked Then
tcs.TrySetResult(ShowContextMenuResponse.Close())
End If
RemoveHandler popupMenu.Closed, menuOnClosed
End Sub
AddHandler popupMenu.Closed, menuOnClosed
' 显示上下文菜单。
Dim location As New Point(parameters.Location.X, parameters.Location.Y)
popupMenu.Show(Me, location)
tcs.TrySetResult(ShowContextMenuResponse.Close())
End Sub))
Else
tcs.TrySetResult(ShowContextMenuResponse.Close())
End If
Return tcs.Task
End Function
WPF
browser.ShowContextMenuHandler =
new AsyncHandler<ShowContextMenuParameters,
ShowContextMenuResponse>(ShowContextMenu);
browser.ShowContextMenuHandler =
New AsyncHandler(Of ShowContextMenuParameters, ShowContextMenuResponse )(
AddressOf ShowContextMenu)
private Task<ShowContextMenuResponse> ShowContextMenu(
ShowContextMenuParameters parameters)
{
TaskCompletionSource<ShowContextMenuResponse> tcs =
new TaskCompletionSource<ShowContextMenuResponse>();
WebView.Dispatcher?.BeginInvoke(new Action(() =>
{
System.Windows.Controls.ContextMenu popupMenu =
new System.Windows.Controls.ContextMenu();
if (!string.IsNullOrEmpty(parameters.LinkText))
{
MenuItem buildMenuItem =
BuildMenuItem("Show the URL link", true,
Visibility.Visible,
(sender, args) =>
{
string linkURL = parameters.LinkUrl;
Console.WriteLine($"linkURL = {linkURL}");
MessageBox.Show(linkURL, "URL");
tcs.TrySetResult(ShowContextMenuResponse.Close());
});
popupMenu.Items.Add(buildMenuItem);
}
MenuItem reloadMenuItem =
BuildMenuItem("Reload", true, Visibility.Visible,
(sender, args) =>
{
Console.WriteLine("Reload current web page");
browser.Navigation.Reload();
tcs.TrySetResult(ShowContextMenuResponse.Close());
});
popupMenu.Items.Add(reloadMenuItem);
popupMenu.Closed += (sender, args) =>
{
tcs.TrySetResult(ShowContextMenuResponse.Close());
};
popupMenu.IsOpen = true;
}));
return tcs.Task;
}
Private Function ShowContextMenu(parameters As ShowContextMenuParameters) _
As Task(Of ShowContextMenuResponse)
Dim tcs As New TaskCompletionSource(Of ShowContextMenuResponse)()
WebView.Dispatcher?.BeginInvoke(New Action(Sub()
Dim popupMenu As New ContextMenu()
If Not String.IsNullOrEmpty(parameters.LinkText) Then
Dim linkMenuItem As MenuItem =
BuildMenuItem("Show the URL link", True,
Visibility.Visible,
Sub(sender, args)
Dim linkUrl As String = parameters.LinkUrl
Debug.WriteLine( $"linkURL = {linkUrl}")
MessageBox.Show(linkUrl,"URL")
tcs.TrySetResult(ShowContextMenuResponse.Close())
End Sub)
popupMenu.Items.Add(linkMenuItem)
End If
Dim reloadMenuItem As MenuItem =
BuildMenuItem("Reload", True, Visibility.Visible,
Sub(sender, args)
Debug.WriteLine("Reload current web page")
browser.Navigation.Reload()
tcs.TrySetResult(ShowContextMenuResponse.Close())
End Sub)
popupMenu.Items.Add(reloadMenuItem)
AddHandler popupMenu.Closed, Sub(sender, args)
tcs.TrySetResult(ShowContextMenuResponse.Close())
End Sub
popupMenu.IsOpen = True
End Sub))
Return tcs.Task
End Function
Avalonia UI
browser.ShowContextMenuHandler =
new AsyncHandler<ShowContextMenuParameters,
ShowContextMenuResponse>(ShowContextMenu);
private Task<ShowContextMenuResponse> ShowContextMenu(
ShowContextMenuParameters parameters)
{
TaskCompletionSource<ShowContextMenuResponse> tcs =
new TaskCompletionSource<ShowContextMenuResponse>();
Dispatcher.UIThread.InvokeAsync(() =>
{
Avalonia.Controls.ContextMenu? cm = new();
cm.Placement = PlacementMode.Pointer;
Point point = new Point(parameters.Location.X, parameters.Location.Y);
cm.PlacementRect = new Rect(point, new Size(1, 1));
if (!string.IsNullOrEmpty(parameters.LinkText))
{
MenuItem buildMenuItem =
BuildMenuItem("Show the URL link", true, true,
async (sender, args) =>
{
string linkURL = parameters.LinkUrl;
Console.WriteLine($"linkURL = {linkURL}");
var box =
MessageBoxManager
.GetMessageBoxStandard("URL", linkURL);
var result = await box.ShowAsync();
tcs.TrySetResult(ShowContextMenuResponse.Close());
});
cm.Items.Add(buildMenuItem);
}
MenuItem reloadMenuItem =
BuildMenuItem("Reload", true, true,
(sender, args) =>
{
Console.WriteLine("Reload current web page");
browser.Navigation.Reload();
tcs.TrySetResult(ShowContextMenuResponse.Close());
});
cm.Items.Add(reloadMenuItem);
cm.Closed += (s, a) => tcs.TrySetResult(ShowContextMenuResponse.Close());
cm.Open(BrowserView);
});
return tcs.Task;
}
我们的存储库中提供了完整的实例: C#
禁用上下文菜单
要完全抑制上下文菜单,应使用以下代码:
browser.ShowContextMenuHandler =
new Handler<ShowContextMenuParameters, ShowContextMenuResponse>(p =>
{
return ShowContextMenuResponse.Close();
});
browser.ShowContextMenuHandler =
New Handler(Of ShowContextMenuParameters, ShowContextMenuResponse)(Function(p)
Return ShowContextMenuResponse.Close()
End Function)