尝试使用CefSharp.ChromiumWebBrowser将XAML绑定到VM在WPF中似乎不起作用
我们直接联系了CEFSharp,让我在这里发布。下面是: 我很好奇,因为我克隆了CEF在这里提供的解决方案:。我看到上下文菜单的所有调用都是通过实现“IContextMenuHandler”在代码隐藏中完成的。是否有任何方法可以直接在XAML中调用上下文菜单,如:尝试使用CefSharp.ChromiumWebBrowser将XAML绑定到VM在WPF中似乎不起作用,wpf,xaml,chromium-embedded,cefsharp,Wpf,Xaml,Chromium Embedded,Cefsharp,我们直接联系了CEFSharp,让我在这里发布。下面是: 我很好奇,因为我克隆了CEF在这里提供的解决方案:。我看到上下文菜单的所有调用都是通过实现“IContextMenuHandler”在代码隐藏中完成的。是否有任何方法可以直接在XAML中调用上下文菜单,如: <cefSharp:ChromiumWebBrowser x:Name="browser" Address="http://www.google.com"> <FrameworkElement.ContextMen
<cefSharp:ChromiumWebBrowser x:Name="browser" Address="http://www.google.com">
<FrameworkElement.ContextMenu>
<ContextMenu >
<MenuItem Header="Run It" Command="{Binding CommandRun}" / >
</ContextMenu >
</FrameworkElement.ContextMenu>
</cefSharp:ChromiumWebBrowser>
然后我可以通过延迟操作调用VM命令,直到单击菜单项。这就完成了所有工作,您可以自由使用我的回购:。然而这有点混乱,我希望我可以直接在xaml中完成这项工作。有人知道吗?我想我至少可以在我的虚拟机中添加一个'CefSharp.WebBrowser'属性,并可能直接在那里调用所有上下文菜单(在撰写本文时还没有尝试过)。这可能会给虚拟机带来更多负担
感谢您可以将浏览器绑定到您的viewmodel,请仔细查看示例我认为上下文菜单的动态特性不适合在xaml中绑定。欢迎您分析源代码并提交PR,以使控件对mvvm更友好。作为参考,上游API文档正在将浏览器与!=。。。直接装订的物品。在某一点上,如果您不提供xaml,而只是在ViewModel中动态构建一个对象来代替xaml,那么您实际上是在让虚拟机像虚拟机内部的视图一样运行。并不是所有东西都能很好地放在一个整洁的小mvvm框中,其核心是围绕Chromium嵌入式框架的包装器。欢迎您参与进来,使控件更易于mvvm。您可以实现一个纯xaml上下文菜单,但不会得到任何上下文特定的菜单项。
lines 437-467 show this
<!--<FrameworkElement.ContextMenu>
<ContextMenu>
<MenuItem Header="Back"
Command="{Binding WebBrowser.BackCommand}" />
<MenuItem Header="Forward"
Command="{Binding WebBrowser.ForwardCommand}" />
<Separator />
<MenuItem Header="Print ..."
Command="{Binding WebBrowser.PrintCommand}" />
<Separator />
<MenuItem Header="Zoom In"
Command="{Binding WebBrowser.ZoomInCommand}" />
<MenuItem Header="Zoom Out"
Command="{Binding WebBrowser.ZoomOutCommand}" />
<MenuItem Header="Zoom Reset"
Command="{Binding WebBrowser.ZoomResetCommand}" />
<Separator />
<MenuItem Header="Show DevTools"
Command="{Binding ShowDevToolsCommand}" />
<MenuItem Header="Close DevTools"
Command="{Binding CloseDevToolsCommand}" />
<Separator />
<MenuItem Header="View Source"
Command="{Binding WebBrowser.ViewSourceCommand}" />
<MenuItem Header="Cut" Command="{Binding WebBrowser.CutCommand}"/>
<MenuItem Header="Copy" Command="{Binding WebBrowser.CopyCommand}"/>
<MenuItem Header="Paste" Command="{Binding WebBrowser.PasteCommand}"/>
</ContextMenu>
</FrameworkElement.ContextMenu>-->
public class BrowserContextMenuHandler : IContextMenuHandler
{
private Action<IMenuModel> _menu;
private Func<CefMenuCommand, bool> _menuCommands;
public BrowserContextMenuHandler(Action<IMenuModel> menu, Func<CefMenuCommand, bool> menuCommands)
{
_menu = menu;
_menuCommands = menuCommands;
}
public void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model) =>
_menu(model);
public bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags) => _menuCommands(commandId);
public void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame)
{
var chromiumWebBrowser = (ChromiumWebBrowser)browserControl;
chromiumWebBrowser.Dispatcher.Invoke(() =>
{
chromiumWebBrowser.ContextMenu = null;
});
}
public bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback) => false;
}
<cefSharp:ChromiumWebBrowser Grid.Row="1" x:Name="browser" Address="http://www.google.com">
private MainWindowViewModel _vm;
public MainWindow()
{
InitializeComponent();
_vm = new MainWindowViewModel();
DataContext = _vm;
browser.MenuHandler = new BrowserContextMenuHandler(menu =>
{
menu.Clear();
menu.AddItem((CefMenuCommand)26501, "Run Test for VM");
menu.AddSeparator();
menu.AddItem((CefMenuCommand)26502, "Hello");
},
commandId =>
{
if (commandId == (CefMenuCommand)26501)
_vm.CommandRun.Execute(null);
if (commandId == (CefMenuCommand)26502)
MessageBox.Show("Hello there");
return true;
});
}