WPF中去边框窗体与WebBrowser控件的兼容问题解决办法

问题产生原因:若设置窗体为AllowsTransparency="True",WindowStyle="None",内嵌的WebBrowser就无法显示了,但它加载的网页内容还能正常交互。

解决方案:

通过google,找到了如下的WPF窗体文件,并对其进行了简单修改。

1.添加一个新窗体,命名为WebBrowserOverlay;

XAML:WebBrowserOverlay.xaml


    

    
C#:WebBrowserOverlay.xaml.cs
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media;


namespace WpfUI
{
    /// 
    /// Displays a WebBrowser control over a given placement target element in a WPF Window.
    /// The owner window can be transparent, but not this one, due mixing DirectX and GDI drawing. 
    /// WebBrowserOverlayWF uses WinForms to avoid this limitation.
    /// 
    public partial class WebBrowserOverlay : Window
    {
        FrameworkElement _placementTarget;


        public WebBrowser WebBrowser { get { return _wb; } }


        public WebBrowserOverlay(FrameworkElement placementTarget)
        {
            InitializeComponent();


            _placementTarget = placementTarget;
            Window owner = Window.GetWindow(placementTarget);
            Debug.Assert(owner != null);


            //owner.SizeChanged += delegate { OnSizeLocationChanged(); };
            owner.LocationChanged += delegate { OnSizeLocationChanged(); };
            _placementTarget.SizeChanged += delegate { OnSizeLocationChanged(); };


            if (owner.IsVisible)
            {
                Owner = owner;
                Show();
            }
            else
                owner.IsVisibleChanged += delegate
                {
                    if (owner.IsVisible)
                    {
                        Owner = owner;
                        Show();
                    }
                };


            //owner.LayoutUpdated += new EventHandler(OnOwnerLayoutUpdated);
        }


        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);
            if (!e.Cancel)
                // Delayed call to avoid crash due to Window bug.
                Dispatcher.BeginInvoke((Action)delegate
                {
                    Owner.Close();
                });
        }


        void OnSizeLocationChanged()
        {
            Point offset = _placementTarget.TranslatePoint(new Point(), Owner);
            Point size = new Point(_placementTarget.ActualWidth, _placementTarget.ActualHeight);
            HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(Owner);
            CompositionTarget ct = hwndSource.CompositionTarget;
            offset = ct.TransformToDevice.Transform(offset);
            size = ct.TransformToDevice.Transform(size);


            Win32.POINT screenLocation = new Win32.POINT(offset);
            Win32.ClientToScreen(hwndSource.Handle, ref screenLocation);
            Win32.POINT screenSize = new Win32.POINT(size);


            Win32.MoveWindow(((HwndSource)HwndSource.FromVisual(this)).Handle, screenLocation.X, screenLocation.Y, screenSize.X, screenSize.Y, true);
        }
    }
}

2.在主窗体中加入一个关闭按钮和一个命名为BdBrowser的Border元素,再在BdBrowser中添加一个WebBrowser控件;

	
		
		
			
		
	

3.加载调用。

            var w = new WpfUI.WebBrowserOverlay(BdBrowser);
            var wb = w.WebBrowser;
            wb.Navigate(new System.Uri("http://www.baidu.com/"));

由于WPF中的WebBrowser功能远没有WinForm中的强大,所以我尝试着在WPF中嵌入WinForm的WebBrowser,方案如下(只贴了修改部分的代码,其他同上):

1.添加引用System.Windows.Forms和WindowsFormsIntegration;

2.在WebBrowserOverlay.xaml中嵌入WindowsFormsHost以承载WinForm的WebBrowser控件


    
        
    

3.WebBrowserOverlay.xaml.cs中将System.Windows.Controls.WebBrowser替换成System.Windows.Forms.WebBrowser;

        public System.Windows.Forms.WebBrowser WebBrowser { get { return _wb; } }

4.主窗体不做改变,但是我稍微改动了一下,以便后续开发。加了一个TextBox作为地址栏,一个Button作为跳转按钮,功能简略,各位看官可以跳过。

using System.Windows;

namespace WpfUI
{
	/// 
	/// MainWindow.xaml 的交互逻辑
	/// 
    public partial class MainWindow : Window
    {
        private WebBrowserOverlay wbo;
        private System.Windows.Forms.WebBrowser fwb;
        public MainWindow()
        {
            this.InitializeComponent();

            // 在此点下面插入创建对象所需的代码。
            wbo = new WebBrowserOverlay(BdBrowser);
            fwb = wbo.WebBrowser;
            fwb.Navigate(new System.Uri(TbAddress.Text));
        }

        private void BtnClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void BtnGo_Click(object sender, RoutedEventArgs e)
        {
            string add = TbAddress.Text;
            fwb.Navigate(new System.Uri(add));
        }

    }
}

源码资源下载:http://download.csdn.net/detail/danding_ge/7167399

你可能感兴趣的:(C#,wpf,webbrowser,winform)