尝试使用CefSharp.ChromiumWebBrowser将XAML绑定到VM在WPF中似乎不起作用

尝试使用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,让我在这里发布。下面是:

我很好奇,因为我克隆了CEF在这里提供的解决方案:。我看到上下文菜单的所有调用都是通过实现“IContextMenuHandler”在代码隐藏中完成的。是否有任何方法可以直接在XAML中调用上下文菜单,如:

<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;
            });
    }