CefSharp是谷歌浏览器的内核开源库,WPF的相关库为CefSharp.wpf,我用的是49.0.1版本的CefSharp.Wpf,但貌似在并不支持触屏的滚动功能,所以就自己写了个附加的触屏功能,暂时只有滚动功能,代码如下:
1.附加类及属性:
/// <summary>
/// 附加功能:CEF的触屏功能
/// </summary>
public class CefTouch : DependencyObject
{
#region Property.Attached - Scrolling
public static bool GetScrolling(DependencyObject obj)
{
return (bool)obj.GetValue(ScrollingProperty);
}
public static void SetScrolling(DependencyObject obj, bool value)
{
obj.SetValue(ScrollingProperty, value);
}
/// <summary> G/S:滚动功能 </summary>
public bool Scrolling
{
get { return (bool)GetValue(ScrollingProperty); }
set { SetValue(ScrollingProperty, value); }
}
public static readonly DependencyProperty ScrollingProperty =
DependencyProperty.RegisterAttached("Scrolling", typeof(bool), typeof(CefTouch), new UIPropertyMetadata(false, _OnScrollingChanged));
static void _OnScrollingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (!(sender is FrameworkElement _target)) { return; }
if ((bool)e.NewValue)
{
_target.Loaded += _OnLoaded;
}
else
{
_OnUnloaded(_target, new RoutedEventArgs());
}
}
#endregion
#region Functions.Scrolling
/// <summary> G/S:捕获的触屏数据 </summary>
private static readonly Dictionary<object, CefTouchCapture> _Captures = new Dictionary<object, CefTouchCapture>();
private static void _OnLoaded(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Scrolling Touched Loaded");
if (!(sender is FrameworkElement _target)) { return; }
_target.Unloaded += _OnUnloaded;
_target.TouchDown += _OnDown;
_target.TouchMove += _OnMove;
_target.TouchUp += _OnUp;
_target.TouchLeave += _OnUp;
}
private static void _OnUnloaded(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Scrolling Touched Unloaded");
if (!(sender is FrameworkElement _target)) { return; }
_Captures.Remove(sender);
_target.Loaded -= _OnLoaded;
_target.Unloaded -= _OnUnloaded;
_target.TouchDown -= _OnDown;
_target.TouchMove -= _OnMove;
_target.TouchUp -= _OnUp;
_target.TouchLeave -= _OnUp;
}
private static void _OnDown(object sender, TouchEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Scrolling Touch Down");
IWebBrowser _webBrowser = null;
CefTouchCapture _capture = null;
if (!_Captures.ContainsKey(sender))
{
_webBrowser = (sender as IWebBrowser);
if (_webBrowser == null)
{
_webBrowser = WPFUntity.FindFirstVisualChild<ChromiumWebBrowser>(sender as DependencyObject);
}
}
else
{
_capture = _Captures[sender];
if (_capture == null) { return; }
_webBrowser = _capture.Browser;
}
if (_webBrowser == null) { return; }
if (_capture == null)
{
_capture = new CefTouchCapture();
}
_capture.IsMouseDown = true;
_capture.Point = null;
_capture.MoveTime = DateTime.Now;
_capture.Browser = _webBrowser;
_capture.Host = _webBrowser.GetBrowser().GetHost();
_Captures[sender] = _capture;
}
private static void _OnUp(object sender, TouchEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Scrolling Touch Up");
if (!_Captures.ContainsKey(sender)) { return; }
var _capture = _Captures[sender];
if (_capture == null) { return; }
_capture.IsMouseDown = false;
_capture.Point = null;
}
private static void _OnMove(object sender, TouchEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Scrolling Touch Move");
if (!_Captures.ContainsKey(sender)) { return; }
var _capture = _Captures[sender];
if (_capture == null) { return; }
if ((DateTime.Now - _capture.MoveTime).TotalMilliseconds < 150) { return; }
if (!(sender is IInputElement _ielement)) { return; }
if (_capture.Host != null && _capture.IsMouseDown)
{
System.Diagnostics.Debug.WriteLine("Scrolling Touch Move - Moved");
_capture.MoveTime = DateTime.Now;
TouchPoint _tPoint = e.GetTouchPoint(_ielement);
Point _newPoint = _tPoint.Position;
if (!_capture.Point.HasValue)
{
_capture.Point = _newPoint;
}
int _x = (int)_newPoint.X;
int _y = (int)_newPoint.Y;
int _oldX = (int)_capture.Point.Value.X;
int _oldy = (int)_capture.Point.Value.Y;
_capture.Host.SendMouseWheelEvent(_x, _y, 0, _y - _oldy, CefEventFlags.MiddleMouseButton);
_capture.Point = _newPoint;
}
}
#endregion
#region Class
/// <summary>
/// Class:CEF的触屏捕获
/// </summary>
internal class CefTouchCapture
{
public DateTime MoveTime { get; set; }
public IBrowserHost Host { get; set; }
public IWebBrowser Browser { get; set; }
public bool IsMouseDown { get; set; }
public Point? Point { get; set; }
}
#endregion
}
2.在Xaml上的使用方式:
<ctl:CefBrowser ctl:CefTouch.Scrolling="True" />