【问题标题】:How to implement Text Search in CefSharp如何在 CefSharp 中实现文本搜索
【发布时间】:2016-06-23 09:52:42
【问题描述】:

我正在使用 CefSharp 构建一个应用程序,并且需要像 Google Chrome 一样向用户提供文本搜索功能。

谁能帮我在 CefSharp 中实现文本搜索?

【问题讨论】:

    标签: c# cefsharp text-search


    【解决方案1】:

    我已经使用 CefSharp 47.0.3 构建了这个演示应用程序,希望这就是您想要的。

    观点:

    <Window x:Class="CefSharpSearchDemo.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            xmlns:cefSharpSearchDemo="clr-namespace:CefSharpSearchDemo"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525"
            d:DataContext="{d:DesignInstance {x:Type cefSharpSearchDemo:MainWindowViewModel}}">
        <DockPanel>
            <DockPanel DockPanel.Dock="Top">
                <Button Content="Next" DockPanel.Dock="Right" Command="{Binding ElementName=SearchBehavior, Path=NextCommand}" />
                <Button Content="Previous" DockPanel.Dock="Right" Command="{Binding ElementName=SearchBehavior, Path=PreviousCommand}"  />
                <TextBox DockPanel.Dock="Right" Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"></TextBox>
            </DockPanel>
    
            <wpf:ChromiumWebBrowser x:Name="wb" DockPanel.Dock="Bottom"
                                    Address="http://stackoverflow.com">
                <i:Interaction.Behaviors>
                    <cefSharpSearchDemo:ChromiumWebBrowserSearchBehavior x:Name="SearchBehavior" SearchText="{Binding SearchText}" />
                </i:Interaction.Behaviors>
            </wpf:ChromiumWebBrowser>
        </DockPanel>
    </Window>
    

    视图的代码隐藏:

    namespace CefSharpSearchDemo
    {
        using System.Windows;
    
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                DataContext = new MainWindowViewModel();
            }
        }
    }
    

    视图模型:

    namespace CefSharpSearchDemo
    {
        using System.ComponentModel;
        using System.Runtime.CompilerServices;
    
        public class MainWindowViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            private string _searchText;
    
            public string SearchText
            {
                get { return _searchText; }
                set
                {
                    _searchText = value;
                    NotifyPropertyChanged();
                }
            }
    
            protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
            {
                var handler = PropertyChanged;
                if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    现在是重要的部分。正如您在视图中看到的那样,ChromiumWebBrowser 附加了一个行为:

    namespace CefSharpSearchDemo
    {
        using System.Windows;
        using System.Windows.Input;
        using System.Windows.Interactivity;
        using CefSharp;
        using CefSharp.Wpf;
    
        public class ChromiumWebBrowserSearchBehavior : Behavior<ChromiumWebBrowser>
        {
            private bool _isSearchEnabled;
    
            public ChromiumWebBrowserSearchBehavior()
            {
                NextCommand = new DelegateCommand(OnNext);
                PreviousCommand = new DelegateCommand(OnPrevious);
            }
    
            private void OnNext()
            {
                AssociatedObject.Find(identifier: 1, searchText: SearchText, forward: true, matchCase: false, findNext: true);
            }
    
            private void OnPrevious()
            {
                AssociatedObject.Find(identifier: 1, searchText: SearchText, forward: false, matchCase: false, findNext: true);
            }
    
            protected override void OnAttached()
            {
                AssociatedObject.FrameLoadEnd += ChromiumWebBrowserOnFrameLoadEnd;
            }
    
            private void ChromiumWebBrowserOnFrameLoadEnd(object sender, FrameLoadEndEventArgs frameLoadEndEventArgs)
            {
                _isSearchEnabled = frameLoadEndEventArgs.Frame.IsMain;
    
                Dispatcher.Invoke(() =>
                {
                    if (_isSearchEnabled && !string.IsNullOrEmpty(SearchText))
                    {
                        AssociatedObject.Find(1, SearchText, true, false, false);
                    }
                });
            }
    
            public static readonly DependencyProperty SearchTextProperty = DependencyProperty.Register(
                "SearchText", typeof(string), typeof(ChromiumWebBrowserSearchBehavior), new PropertyMetadata(default(string), OnSearchTextChanged));
    
            public string SearchText
            {
                get { return (string)GetValue(SearchTextProperty); }
                set { SetValue(SearchTextProperty, value); }
            }
    
            public static readonly DependencyProperty NextCommandProperty = DependencyProperty.Register(
                "NextCommand", typeof (ICommand), typeof (ChromiumWebBrowserSearchBehavior), new PropertyMetadata(default(ICommand)));
    
            public ICommand NextCommand
            {
                get { return (ICommand) GetValue(NextCommandProperty); }
                set { SetValue(NextCommandProperty, value); }
            }
    
            public static readonly DependencyProperty PreviousCommandProperty = DependencyProperty.Register(
                "PreviousCommand", typeof (ICommand), typeof (ChromiumWebBrowserSearchBehavior), new PropertyMetadata(default(ICommand)));
    
            public ICommand PreviousCommand
            {
                get { return (ICommand) GetValue(PreviousCommandProperty); }
                set { SetValue(PreviousCommandProperty, value); }
            }
    
            private static void OnSearchTextChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
            {
                var behavior = dependencyObject as ChromiumWebBrowserSearchBehavior;
    
                if (behavior != null && behavior._isSearchEnabled)
                {
                    var newSearchText = dependencyPropertyChangedEventArgs.NewValue as string;
    
                    if (string.IsNullOrEmpty(newSearchText))
                    {
                        behavior.AssociatedObject.StopFinding(true);
                    }
                    else
                    {
                        behavior.AssociatedObject.Find(1, newSearchText, true, false, false);
                    }
                }
            }
    
            protected override void OnDetaching()
            {
                AssociatedObject.FrameLoadEnd -= ChromiumWebBrowserOnFrameLoadEnd;
            }
        }
    }
    

    以及DelegateCommand 的次要附加代码:

    namespace CefSharpSearchDemo
    {
        using System;
        using System.Windows.Input;
    
        public class DelegateCommand : ICommand
        {
            private readonly Action _action;
    
            public DelegateCommand(Action action)
            {
                _action = action;
            }
    
            public bool CanExecute(object parameter)
            {
                return true;
            }
    
            public void Execute(object parameter)
            {
                _action();
            }
    
            public event EventHandler CanExecuteChanged;
        }
    }
    

    生成的应用程序顶部有一个TextBox,旁边有两个标记为“上一个”和“下一个”的按钮。

    主要区域是加载http://www.stackoverflow.com的CefSharp浏览器。

    您可以输入TextBox,它会在浏览器中搜索(并突出显示命中的滚动条,就像在 Chrome 中一样)。然后,您可以按 Next/Previous 按钮来循环点击。

    我希望这有助于您开发自己的解决方案。

    说了这么多,让我注意下次如果您提出问题,请实际提供一些您尝试过的代码,或者尝试提出更具体的问题,因为这对于本网站来说可能过于宽泛。不管怎样,我把它留在这里,也许其他人也会觉得它有用。

    重要一课:ChromiumWebBrowser 上公开了一些方法,您可以使用它们来实现搜索功能(即:FindStopFinding)。

    【讨论】:

      【解决方案2】:

      您只需在表单上添加两个buttons 和一个textbox 即可。 第一个 buttons 用于下一个结果,第二个 buttons 用于上一个结果,textbox 用于搜索文本提供程序。

      文本框的 KeyUp 事件在代码下方运行

      if (tosBrowserSearchTxt.Text.Length <= 0)
      {
          //this will clear all search result
          webBrowserChromium.StopFinding(true);
      }
      else
      {
          webBrowserChromium.Find(0, tosBrowserSearchTxt.Text, true, false,false);
      }
      

      在下一个按钮上点击下面的代码运行

      webBrowserChromium.Find(0, tosBrowserSearchTxt.Text, true, false, false); 
      

      在上一个按钮上点击下面的代码运行

      webBrowserChromium.Find(0, tosBrowserSearchTxt.Text, false, false, false);
      

      当用户在文本框中键入任何字符时,KeyUp 事件的代码将搜索该文本,通过使用下一个和上一个按钮,您可以从一个结果导航到另一个结果。

      【讨论】:

        猜你喜欢
        • 2010-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-22
        • 2014-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多