2016-04-18 12 views
1

Мне нужно добавить WebBrowser элемент управления для динамически генерируемого Window в приложении WPF.Добавление System.Windows.Forms.WebBrowser в System.Windows.Controls.StackPanel не может преобразовать в System.Windows.UIElement

Обычно, когда агент нажимает на ссылку, мне нужно открыть окно webbrowser, у которого кнопка закрытия (X) отключена (или скрыта) на некоторых страницах, а не на других. Причина в том, что они перенаправляются на стороннюю платежную систему, которая собирает платеж, и если они закрывают окно браузера после сбора платежа, но до того, как они будут перенаправлены обратно в нашу систему, мы не получаем уведомления об оплате, в то время как сторонняя сторона взимает плату с наших клиентов.

Первоначально окно веб-браузера было открыто в Windows.Form, но мне не удалось найти способ отключить X в форме, поэтому я решил переключиться на окно WPF, так как наше приложение - это WPF, поэтому я представил окно и панель но теперь, когда динамическое добавление WebBrowser управления панелью Children это дает следующее сообщение об ошибке

ошибка не может конвертировать из «Desktop.ViewModels.PaymentViewModel.NavigateToTakePaymentCommand.MyWebBrowser» к «System.Windows.UIElement»

private void OpenBrowser(PaymentViewModel viewModel, Uri uri) 
{ 
    viewModel.BrowserWindow = new WithoutCloseButton(); 
    viewModel.BrowserWindow.Closed += BrowserWindow_Closed; 
    var browser = new MyWebBrowser(); 
    var stackPanel = new StackPanel { Orientation = System.Windows.Controls.Orientation.Vertical }; 
    stackPanel.Children.Add(browser); // this bit fails 
    viewModel.BrowserWindow.Content = stackPanel; 

...

public class WithoutCloseButton : Window 
{ 
    private const int GWL_STYLE = -16; 
    private const int WS_SYSMENU = 0x80000; 
    [DllImport("user32.dll", SetLastError = true)] 
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex); 
    [DllImport("user32.dll")] 
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 
} 

public class MyWebBrowser : System.Windows.Forms.WebBrowser 
{ 
    public static Guid IID_IHttpSecurity 
     = new Guid("79eac9d7-bafa-11ce-8c82-00aa004ba90b"); 
    public static Guid IID_IWindowForBindingUI 
     = new Guid("79eac9d5-bafa-11ce-8c82-00aa004ba90b"); 
    public const int S_OK = 0; 
    public const int S_FALSE = 1; 
    public const int E_NOINTERFACE = unchecked((int)0x80004002); 
    public const int RPC_E_RETRY = unchecked((int)0x80010109); 
    protected override WebBrowserSiteBase CreateWebBrowserSiteBase() 
    { 
     return new MyWebBrowserSite(this); 
    } 

    class MyWebBrowserSite : WebBrowserSite, UCOMIServiceProvider,IHttpSecurity, IWindowForBindingUI 
    { 
     private MyWebBrowser myWebBrowser; 
     public MyWebBrowserSite(MyWebBrowser myWebBrowser) : base(myWebBrowser) 
     { 
      this.myWebBrowser = myWebBrowser; 
     } 

     public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject) 
     { 
      if (riid == IID_IHttpSecurity) 
      { 
       ppvObject = Marshal.GetComInterfaceForObject(this 
        , typeof(IHttpSecurity)); 
       return S_OK; 
      } 
      if (riid == IID_IWindowForBindingUI) 
      { 
       ppvObject = Marshal.GetComInterfaceForObject(this 
        , typeof(IWindowForBindingUI)); 
       return S_OK; 
      } 
      ppvObject = IntPtr.Zero; 
      return E_NOINTERFACE; 
     } 

     public int GetWindow(ref Guid rguidReason , ref IntPtr phwnd) 
     { 
      if (rguidReason == IID_IHttpSecurity || rguidReason == IID_IWindowForBindingUI) 
      { 
       phwnd = myWebBrowser.Handle; 
       return S_OK; 
      } 
      else 
      { 
       phwnd = IntPtr.Zero; 
       return S_FALSE; 
      } 
     } 

     public int OnSecurityProblem(uint dwProblem) 
     { 
      //ignore errors 
      //undocumented return code, does not work on IE6 
      return S_OK; 
     } 
    } 
} 

Как добавить System.Windows.Forms.WebBrowser к System.Windows.Controls.StackPanel? Есть что-то вроде обертки?

+0

Вы должны использовать System.Windows.Controls.WebBrowser https://msdn.microsoft.com/en-us/library /system.windows.controls.webbrowser.aspx или разместить браузер Windows Forms в элементе управления WPF. –

+0

как для обертки, проверьте это: http://www.wpf-tutorial.com/misc-controls/the-windowsformshost-control/ –

+0

@SideriteZackwehdex Привет, спасибо за ответ. System.Windows.Controls.WebBrowsr запечатан Я не могу наследовать его –

ответ

0

С помощью @Siderite Zackwehdex

мне пришлось добавить ссылку до WindowsFormsIntegration. Перейдите к проекту и развернителю References ->Add Reference ->Assemblies ->Framework -> галочка WindowsFormsIntegration.

enter image description here

Тогда я должен был изменить следующие биты.

public class WithoutCloseButton : Window 
     { 
      private const int GWL_STYLE = -16; 
      private const int WS_SYSMENU = 0x80000; 

      [DllImport("user32.dll", SetLastError = true)] 
      private static extern int GetWindowLong(IntPtr hWnd, int nIndex); 
      [DllImport("user32.dll")] 
      private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 

//THIS IS NEW 
      public void HideButtons() 
      { 
       var hwnd = new WindowInteropHelper(this).Handle; 
       SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU); 
      } 
     } 

, а затем в OpenBrowser() мне пришлось обернуть WebBrowser в WindowsFormsHost

private void OpenBrowser(PaymentViewModel viewModel, Uri uri) 
{ 
    viewModel.BrowserWindow = new WithoutCloseButton(); 
    viewModel.BrowserWindow.Closed += BrowserWindow_Closed; 
    var browser = new MyWebBrowser(); 
    var stackPanel = new StackPanel { Orientation = System.Windows.Controls.Orientation.Vertical }; 
    var formsHost = new WindowsFormsHost {Child = browser}; 
    stackPanel.Children.Add(formsHost); 
    viewModel.BrowserWindow.Content = stackPanel; 
//.... then    
browser.Navigate("about:blank"); 
browser.DocumentCompleted += delegate(object obj, WebBrowserDocumentCompletedEventArgs e) 
{ 
    if (e.Url.ToString() == "about:blank") 
    { 
     ((MyWebBrowser)obj).Navigate(uri); 
    } 

    if (e.Url.ToString().ToLower().Contains("accepted")) 
    { 
     ViewModel.AuthCode = this.GetAuthToken(); 
     ViewModel.updateUiWhenDoneWithPayment_RunWorkerCompleted(new object(), null); 
     ViewModel.BrowserWindow.Close(); 
     ViewModel.BrowserWindow = null; 
    } 
    //THIS IS NEW 
    if (e.Url.ToString().ToLower().Contains("payment/confirmation")) 
    { 
     viewModel.BrowserWindow.HideButtons(); 
    } 
}; 
0

Чтобы добавить WindowFormcontrols в WPF вам необходимо WindowsFormsHost. Добавьте WindowsFormHost в ваш StackPanel, а затем добавьте webbrowser в WindowsFormHost. XAML примеры приведены ниже:

1.

<WindowsFormsHost> 
     <wf:MaskedTextBox x:Name="mtbDate" Mask="00/00/0000"/> 
    </WindowsFormsHost> 

2.

<wfh:WindowsFormsHost Grid.Row="1" x:Name="wbFormHost" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" TabIndex="6"> 
     <wf:WebBrowser x:Name="webBrowser" x:FieldModifier="public" Dock="Fill"/> 
    </wfh:WindowsFormsHost> 

где wfh является xmlns:wfh="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"

 Смежные вопросы

  • Нет связанных вопросов^_^