首页 > 其他分享 >wpf 覆盖元素在webview2之上

wpf 覆盖元素在webview2之上

时间:2023-09-21 14:13:39浏览次数:91  
标签:Web Microsoft WebView2 元素 System webview2 using wpf public

元素代码来源 github CrissCross项目

需要两个工具类及一个webview2的封装类

// Copyright (c) Chris Pulman. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
namespace WpfApp1
{
    /// <summary>
    /// Window Host.
    /// </summary>
    /// <typeparam name="TWindow">The type of the window to host.</typeparam>
    /// <seealso cref="HwndHost" />
    public class WindowHost<TWindow> : HwndHost
    where TWindow : Window, new()
    {
        private const int GWLSTYLE = -0x10;
        private const uint WSCHILD = 0x40000000u;

        /// <summary>
        /// Initializes a new instance of the <see cref="WindowHost{TWindow}" /> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="window">The window.</param>
        public WindowHost(string name, TWindow? window = null)
        {
            Window = window ??= new();
            Window.Name = name;
            Window.ResizeMode = ResizeMode.NoResize;
            Window.WindowStyle = WindowStyle.None;
            Window.ShowInTaskbar = false;
            Window.AllowsTransparency = true;
            Window.Background = Brushes.Transparent;
            Window.Show();
            WindowHandle = new WindowInteropHelper(Window).Handle;
        }

        /// <summary>
        /// Gets the window handle.
        /// </summary>
        /// <value>
        /// The window handle.
        /// </value>
        public IntPtr WindowHandle { get; }

        /// <summary>
        /// Gets the window.
        /// </summary>
        /// <value>
        /// The window.
        /// </value>
        public TWindow Window { get; }

        /// <summary>
        /// Closes this instance.
        /// </summary>
        public void Close()
        {
            Window.Close();
            DestroyWindowCore(new HandleRef(Window, IntPtr.Zero));
        }

        /// <summary>
        /// When overridden in a derived class, creates the window to be hosted.
        /// </summary>
        /// <param name="hwndParent">The window handle of the parent window.</param>
        /// <returns>
        /// The handle to the child Win32 window to create.
        /// </returns>
        protected override HandleRef BuildWindowCore(HandleRef hwndParent)
        {
            HandleRef href = default;

            if (WindowHandle != IntPtr.Zero)
            {
                _ = NativeMethods.SetWindowLong(WindowHandle, GWLSTYLE, WSCHILD);
                NativeMethods.SetParent(WindowHandle, hwndParent.Handle);
                href = new HandleRef(this, WindowHandle);
            }

            return href;
        }

        /// <summary>
        /// When overridden in a derived class, destroys the hosted window.
        /// </summary>
        /// <param name="hwnd">A structure that contains the window handle.</param>
        protected override void DestroyWindowCore(HandleRef hwnd)
        {
            if (WindowHandle != hwnd.Handle)
            {
                NativeMethods.SetParent(WindowHandle, hwnd.Handle);
            }
        }
    }
}
// Copyright (c) Chris Pulman. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Runtime.InteropServices;

namespace WpfApp1
{
    internal static class NativeMethods
    {
        [DllImport("user32.dll")]
        internal static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll")]
        internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
    }
}
// Copyright (c) Chris Pulman. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Effects;

namespace WpfApp1
{

    /// <summary>
    /// Navigation Web View.
    /// </summary>
    /// <seealso cref="ContentControl" />
    /// <seealso cref="IDisposable" />
    [ToolboxItem(true)]
    public class WebView2Wpf : ContentControl, IDisposable
    {
        private static readonly DependencyPropertyKey CanGoBackPropertyKey = DependencyProperty.RegisterReadOnly(
            nameof(CanGoBack),
            typeof(bool),
            typeof(WebView2Wpf),
            new PropertyMetadata(false));

        private static readonly DependencyPropertyKey CanGoForwardPropertyKey = DependencyProperty.RegisterReadOnly(
            nameof(CanGoForward),
            typeof(bool),
            typeof(WebView2Wpf),
            new PropertyMetadata(false));

#pragma warning disable SA1202 // Elements should be ordered by access

        /// <summary>
        /// The WPF DependencyProperty which backs the Microsoft.Web.WebView2.Wpf.WebView2.CreationProperties property.
        /// </summary>
        public static readonly DependencyProperty CreationPropertiesProperty = DependencyProperty.Register(
            nameof(CreationProperties),
            typeof(CoreWebView2CreationProperties),
            typeof(WebView2Wpf),
            new PropertyMetadata(CreationPropertiesChanged));

        /// <summary>
        /// The WPF DependencyProperty which backs the Microsoft.Web.WebView2.Wpf.WebView2.Source property.
        /// </summary>
        public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
            nameof(Source),
            typeof(Uri),
            typeof(WebView2Wpf),
            new PropertyMetadata(SourceChanged));

        /// <summary>
        /// The WPF DependencyProperty which backs the Microsoft.Web.WebView2.Wpf.WebView2.CanGoBack property.
        /// </summary>
        public static readonly DependencyProperty CanGoBackProperty = CanGoBackPropertyKey!.DependencyProperty;

        /// <summary>
        /// The WPF DependencyProperty which backs the Microsoft.Web.WebView2.Wpf.WebView2.CanGoForward property.
        /// </summary>
        public static readonly DependencyProperty CanGoForwardProperty = CanGoForwardPropertyKey!.DependencyProperty;

        /// <summary>
        /// The WPF DependencyProperty which backs the Microsoft.Web.WebView2.Wpf.WebView2.ZoomFactor property.
        /// </summary>
        public static readonly DependencyProperty ZoomFactorProperty = DependencyProperty.Register(
            nameof(ZoomFactor),
            typeof(double),
            typeof(WebView2Wpf));

        /// <summary>
        /// The navigate back is enabled property.
        /// </summary>
        public static new readonly DependencyProperty ContentProperty = DependencyProperty.Register(
            nameof(Content),
            typeof(object),
            typeof(WebView2Wpf),
            new PropertyMetadata(true, ContentChanged));
#pragma warning restore SA1202 // Elements should be ordered by access

        public readonly WebView2 _WebBrowser;
        private WindowHost<Window>? _windowHost;
        private bool _disposedValue;

        /// <summary>
        /// Initializes a new instance of the <see cref="WebView2Wpf"/> class.
        /// </summary>
        public WebView2Wpf()
        {
            _WebBrowser = new()
            {
                HorizontalAlignment = HorizontalAlignment.Stretch,
                VerticalAlignment = VerticalAlignment.Stretch,
            };
            Unloaded += (s, e) => Dispose();
        }

        /// <summary>
        /// Gets accesses the complete functionality of the underlying Microsoft.Web.WebView2.Core.CoreWebView2
        ///     COM API. Returns null until initialization has completed. See the Microsoft.Web.WebView2.Wpf.WebView2
        ///     class documentation for an initialization overview.
        /// </summary>
        /// <value>
        /// The core web view2.
        /// </value>
        [Browsable(false)]
        public CoreWebView2 CoreWebView2 => _WebBrowser.CoreWebView2;

        /// <summary>
        /// Gets or sets the creation properties.
        /// </summary>
        /// <value>
        /// The creation properties.
        /// </value>
        [Category("Common")]
        public CoreWebView2CreationProperties CreationProperties
        {
            get => (CoreWebView2CreationProperties)GetValue(CreationPropertiesProperty);
            set => SetValue(CreationPropertiesProperty, value);
        }

        /// <summary>
        /// Gets or sets the source.
        /// </summary>
        /// <value>
        /// The source.
        /// </value>
        [Category("Common")]
        public Uri Source
        {
            get => (Uri)GetValue(SourceProperty);
            set => SetValue(SourceProperty, value);
        }

        /// <summary>
        /// Gets a value indicating whether this instance can go back.
        /// if the WebView can navigate to a previous page in the navigation
        ///     history. Wrapper around the Microsoft.Web.WebView2.Core.CoreWebView2.CanGoBack
        ///     property of Microsoft.Web.WebView2.Wpf.WebView2.CoreWebView2. If Microsoft.Web.WebView2.Wpf.WebView2.CoreWebView2
        ///     isn't initialized yet then returns false.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance can go back; otherwise, <c>false</c>.
        /// </value>
        [Browsable(false)]
        public bool CanGoBack => _WebBrowser.CanGoBack;

        /// <summary>
        /// Gets a value indicating whether this instance can go forward.
        /// if the WebView can navigate to a next page in the navigation history.
        ///     Wrapper around the Microsoft.Web.WebView2.Core.CoreWebView2.CanGoForward property
        ///     of Microsoft.Web.WebView2.Wpf.WebView2.CoreWebView2. If Microsoft.Web.WebView2.Wpf.WebView2.CoreWebView2
        ///     isn't initialized yet then returns false.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance can go forward; otherwise, <c>false</c>.
        /// </value>
        [Browsable(false)]
        public bool CanGoForward => _WebBrowser.CanGoForward;

        /// <summary>
        /// Gets or sets a value indicating whether [zoom factor].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [zoom factor]; otherwise, <c>false</c>.
        /// </value>
        [Category("Common")]
        public double ZoomFactor
        {
            get => (double)GetValue(ZoomFactorProperty);
            set => SetValue(ZoomFactorProperty, value);
        }

        /// <summary>
        /// Gets or sets the content of the XAML overlay />.
        /// </summary>
        [Bindable(true)]
        [Category("Content")]
        public new object Content
        {
            get => GetValue(ContentProperty);
            set => SetValue(ContentProperty, value);
        }

        /// <summary>
        /// Gets the opacity mask.
        /// </summary>
        /// <value>
        /// The opacity mask.
        /// </value>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new System.Windows.Media.Brush OpacityMask => _WebBrowser.OpacityMask;

        /// <summary>
        /// Gets the opacity.
        /// </summary>
        /// <value>
        /// The opacity.
        /// </value>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new double Opacity => _WebBrowser.Opacity;

        /// <summary>
        /// Gets the effect.
        /// </summary>
        /// <value>
        /// The effect.
        /// </value>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new Effect Effect => _WebBrowser.Effect;

        /// <summary>
        /// Gets the context menu.
        /// </summary>
        /// <value>
        /// The context menu.
        /// </value>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ContextMenu ContextMenu => _WebBrowser.ContextMenu;

        /// <summary>
        /// Gets the focus visual style.
        /// </summary>
        /// <value>
        /// The focus visual style.
        /// </value>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new Style FocusVisualStyle => _WebBrowser.FocusVisualStyle;

        /// <summary>
        /// Gets the input scope.
        /// </summary>
        /// <value>
        /// The input scope.
        /// </value>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new InputScope InputScope => _WebBrowser.InputScope;

        /// <summary>
        /// Navigates the WebView to the previous page in the navigation history. Equivalent
        ///     to calling Microsoft.Web.WebView2.Core.CoreWebView2.GoBack on Microsoft.Web.WebView2.Wpf.WebView2.CoreWebView2
        ///     If CoreWebView2 hasn't been initialized yet then does nothing.
        /// </summary>
        public void GoBack() => _WebBrowser?.GoBack();

        /// <summary>
        /// Navigates the WebView to the next page in the navigation history. Equivalent
        ///     to calling Microsoft.Web.WebView2.Core.CoreWebView2.GoForward on Microsoft.Web.WebView2.Wpf.WebView2.CoreWebView2
        ///     If CoreWebView2 hasn't been initialized yet then does nothing.
        /// </summary>
        public void GoForward() => _WebBrowser?.GoForward();

        /// <summary>
        /// Reloads the current page. Equivalent to calling Microsoft.Web.WebView2.Core.CoreWebView2.Reload
        ///     on Microsoft.Web.WebView2.Wpf.WebView2.CoreWebView2.
        /// </summary>
        public void Reload() => _WebBrowser?.Reload();

        /// <summary>
        /// Stops all navigations and pending resource fetches. Equivalent to calling Microsoft.Web.WebView2.Core.CoreWebView2.Stop
        ///     on Microsoft.Web.WebView2.Wpf.WebView2.CoreWebView2.
        /// </summary>
        public void Stop() => _WebBrowser?.Stop();

        /// <summary>
        /// Initiates a navigation to htmlContent as source HTML of a new document. Equivalent
        ///     to calling Microsoft.Web.WebView2.Core.CoreWebView2.NavigateToString(System.String)
        ///     on Microsoft.Web.WebView2.Wpf.WebView2.CoreWebView2.
        /// </summary>
        /// <param name="htmlContent">Content of the HTML.</param>
        public void NavigateToString(string htmlContent) => _WebBrowser?.NavigateToString(htmlContent);

        /// <summary>
        /// Executes JavaScript code from the javaScript parameter in the current top level
        ///     document rendered in the WebView. Equivalent to calling Microsoft.Web.WebView2.Core.CoreWebView2.ExecuteScriptAsync(System.String)
        ///     on Microsoft.Web.WebView2.Wpf.WebView2.CoreWebView2.
        /// </summary>
        /// <param name="javaScript">The java script.</param>
        /// <returns>A string.</returns>
        public async Task<string> ExecuteScriptAsync(string javaScript) => await _WebBrowser.ExecuteScriptAsync(javaScript);

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Raises the <see cref="E:System.Windows.FrameworkElement.Initialized" /> event. This method is invoked whenever <see cref="P:System.Windows.FrameworkElement.IsInitialized" /> is set to <see langword="true" /> internally.
        /// </summary>
        /// <param name="e">The <see cref="T:System.Windows.RoutedEventArgs" /> that contains the event data.</param>
        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            _windowHost = new(Name);
            _windowHost.Window.HorizontalAlignment = HorizontalAlignment;
            _windowHost.Window.VerticalAlignment = VerticalAlignment;
            _windowHost.Window.Content = Content;
            var layoutRoot = new Grid();
            layoutRoot.Children.Add(_WebBrowser);
            layoutRoot.Children.Add(_windowHost);
            base.Content = layoutRoot;
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources.
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposedValue)
            {
                if (disposing)
                {
                    _WebBrowser.Dispose();
                    _windowHost?.Close();
                    _windowHost?.Dispose();
                }

                _disposedValue = true;
            }
        }

        private static void CreationPropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is WebView2Wpf browser && e.NewValue is CoreWebView2CreationProperties creationProperties)
            {
                browser._WebBrowser.CreationProperties = creationProperties;
            }
        }

        private static void SourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is WebView2Wpf browser && e.NewValue is Uri source)
            {
                browser._WebBrowser.Source = source;
            }
        }

        private static void ContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is WebView2Wpf browser && browser._windowHost?.Window is not null)
            {
                browser._windowHost.Window.Content = e.NewValue;
            }
        }
    }
}

显示效果

测试代码

<Window x:Class="WpfApp1.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:local="clr-namespace:WpfApp1" 
        xmlns:wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" >
    <Grid >
        <!--<wpf:WebView2 Source="http://www.baidu.com" />-->
        <local:WebView2Wpf x:Name="WebView2Wpf" Source="https://www.google.com" Loaded="WebView2Wpf_Loaded" Panel.ZIndex="-1">
            <Grid>
                <Button Content="I am on top of WebView2 control with Criscross" Height="50" Width="575" FontSize="25" HorizontalAlignment="Center"
                    Foreground="LimeGreen"  />
            </Grid>
        </local:WebView2Wpf>
    </Grid>
</Window>

wpf后台代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void WebView2Wpf_Loaded(object sender, RoutedEventArgs e)
        {
            WebView2Wpf._WebBrowser.Loaded += _WebBrowser_Loaded; ;
        }

        private void _WebBrowser_Loaded(object sender, RoutedEventArgs e)
        {
            WebView2Wpf._WebBrowser.CoreWebView2InitializationCompleted += _WebBrowser_CoreWebView2InitializationCompleted;
        }

        private void _WebBrowser_CoreWebView2InitializationCompleted(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
        {

        }
    }
}

标签:Web,Microsoft,WebView2,元素,System,webview2,using,wpf,public
From: https://www.cnblogs.com/ives/p/17719809.html

相关文章

  • [WPF]万物皆可绑定
    最近一个项目有一个需求,需要在ComboBox中选择时,获得SelecetedValue值并执行一个方法,查了一下可以用Interactivity进行触发器重写,用一个事件来绑定命令。但网上很多资料真的很坑,写了方法但是没提前提条件,需要在NuGet中安装一个Microsoft.Xaml.Behaviors.Wpf包来支持这个功能,然后在......
  • 随想录Day1|704. 二分查找、27. 移除元素
    随想录Day1|704.二分查找、27.移除元素 704.二分查找LeetCode题目文章讲解视频讲解给定n个元素升序的整形数组nums和一个目标值target,写一个函数搜索nums中的target,如果存在目标值则返回下标,否则返回-1。其中nums中的元素不重复,n在[1,10000]之间,nums的每个元素都在[-......
  • 算法学习 |Day 1 数组基础 704. 二分查找,27. 移除元素
    704.二分查找思路:二分查找的前置条件是数组有序且无重复元素,每次通过改变边界值来缩小查找范围。自己写的:可以看到对边界的判断存在问题,基本思路是左闭右闭,但是while循环的判断是按照左闭右开来写的。对于数组中仅包含一个元素且该元素是目标函数的情况会出错。重新调试后......
  • 18 overflow 和父级元素边框塌陷
    父级元素边框塌陷:就是浮动的元素超出父级元素边框解决方法:1.设置父级元素边框大小2.增加一个空标签,清除浮动,把其他浮动挤上去3.父级元素,overflow:hidden;4.滚动条:设置父级元素边框大小,然后overflow:scroll5.父类添加伪类,和2是一样的。推荐使用#father:after{......
  • 探索 WPF 的 ITabletManager.GetTabletCount 在 Win11 系统的底层实现
    本文将和大家介绍专为WPF触摸模块提供的ITabletManager的GetTabletCount方法在Windows11系统的底层实现本文属于WPF触摸相关系列博客,偏系统底层介绍,更多触摸博客请看WPF触摸相关大家都知道在Windows7系统,有专门的笔和触摸服务提供触摸消息的支持。而WPF是从V......
  • WPF TextBlock显示固定长度字符串
    页面中TextBlock控件内容 <TextBlockx:Name="name"HorizontalAlignment="Left"Text="{BindingName,Converter={StaticResourceStringMaxLenConverter},ConverterParameter=13}"TextWrapping="NoWrap"/>设置一个转换器,并且在页面中使用:<......
  • WPF 界面或文本框焦点丢失问题
    在用户界面,有些时候需要使用键盘某个按键触发某项功能,但有时候会有焦点丢失问题发生,解决办法如下: List<T>FindVisualChild<T>(DependencyObjectobj)whereT:DependencyObject{try{List<T>list=newList<T>();......
  • 203.移除链表元素 707.设计链表 206.反转链表
    203.移除链表元素力扣题目链接(opensnewwindow)题意:删除链表中等于给定值val的所有节点。示例1:输入:head=[1,2,6,3,4,5,6],val=6输出:[1,2,3,4,5]示例2:输入:head=[],val=1输出:[]示例3:输入:head=[7,7,7,7],val=7输出:[]思路操作链表的两种方式:直接使用原来的......
  • WPF 踩过的坑
    1,wpf项目复制别人的图片或样式文件,生成报错,需要把文件或图片点击属性设置资源文件2,选项卡设计ui界面时,调整其它面板的控件,设置该属性IsChecked="True"<StackPanelOrientation="Horizontal"VerticalAlignment="Bottom"HorizontalAlignment="Center">......
  • 循环删除 List 中的元素
    一、背景一个需求的技术点,需要循环删除List中的元素二、实现怎么删除List中姓李的人?publicList<String>initList=Arrays.asList("张三","李四","周一","刘四","李强","李白");1、普通for循环删除(不可靠)点击查看代码@Testpublicvoidremove1()......