2012-02-09 2 views
1

МОФ приложения к воспроизводству мой случай (.net 4.0)WindowsFormsHost перехватов сосредоточиться на активизации приложения, даже активирующий по другой форме

  1. Создание приложения WPF (MainWindow.xaml)
  2. Добавить пользовательский элемент управления, который содержит Winform текстовое поле (UserConrol1.cs - Winform)
  3. Поместите UserControl1 в MainWindow.xaml с WindowsFormsHost
  4. Добавить еще одно окно WPF, который содержит текстовое поле (МОФ) проекта (Window1.xaml)
  5. Cr ЭАТС и Показать Window1 после MainWindow InitializeComponent

Ваш проект готов,

  1. Выполнить проект и установить текстовое поле сосредоточено в MainWindow.xaml (что в WindowsFormsHost)
  2. Деактивировать приложение, открыв окно (Windows, файловый менеджер, блокнот, WinAmp и т.д.)
  3. Попробуйте написать в текстовом поле, что в окне Window1, щелкнув текстовое поле с помощью мыши

И вы увидите, что вы не можете установить фокус на текстовое поле в Window1, потому что MainWindow Texbox (в winformshost будет украсть ваш фокус на вашем приложении, активированном)

Любая идея?

MainWindow.xaml

<Window x:Class="WinFormsHostFocusProblem.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WinFormsHostFocusProblem" 
     xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <my:WindowsFormsHost Focusable="False" > 
     <local:UserControl1> 

     </local:UserControl1> 
     </my:WindowsFormsHost> 

    </Grid> 
</Window> 

MainWindow.xaml.cs

namespace WinFormsHostFocusProblem 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
     InitializeComponent(); 
     Window1 window1 = new Window1(); 
     window1.Show(); 
     } 
    } 
} 

Window1.xaml

<Window x:Class="WinFormsHostFocusProblem.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WinFormsHostFocusProblem" 
     xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" 
     SizeToContent="WidthAndHeight" 
     ResizeMode="NoResize" 

     Topmost="True" 
     Title="Window1" Height="300" Width="300" Background="Red"> 
    <Grid> 
     <TextBox Height="25">asd</TextBox> 
    </Grid> 
</Window> 

Window1.xaml.cs

namespace WinFormsHostFocusProblem 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
     InitializeComponent(); 
     } 
    } 
} 

ответ

0

У нас была аналогичная проблема в одном из наших приложений и обнаружили, что обновление до .net 4.5, похоже, закрепилась хорошая часть WPF/WinForms нашего приложения сосредоточены вопросы, в том числе на аналогичный к этому. не

Кроме того, поле _focusedChild больше не существует в версии .net 4.5 WindowsFormsHost

4

Я использовал мой контракт на поддержку MSDN, чтобы получить ответ на эту проблему. Инженер смог воспроизвести у образца yunusayd и подтвердил, что это почти наверняка ошибка в WindowsFormsHost.

Благодаря yunus для минимального образца для воспроизведения и Keith в Microsoft для решения проблемы и обеспечения обходного пути менее чем за один день.

Обходной код следует. Он работает с использованием .NET reflection для изменения частной переменной, используемой в WindowsFormsHost, и отключает триггер для ошибки. По словам инженера, с которым я работал, это зависит от внутренних компонентов WPF, но он говорил с членами группы продуктов, и он должен быть безопасным в использовании. Конечно, нет никаких гарантий отсутствия побочных эффектов, но до сих пор я не обнаружил никаких проблем при тестировании с несколькими WindowsFormsHosts в нескольких окнах WPF (возможно, вложенность была бы сложнее). Я изменил исходное обходное решение для работы в целом с несколькими окнами. Вы также можете легко ссылаться на ссылки на конкретные окна и элементы управления WindowsFormsHost в событии Application_Deactivated и пропускать все схемы и методы расширения LastActive.

// App.xaml.cs: you must hook up to Application.Deactivated 
void Application_Deactivated(object sender, EventArgs e) 
{ 
    foreach (Window w in windows) 
    { 
     foreach (var host in UI.DependencyObjectExtension.AllLogicalChildren(w). 
        Where(c => c is WindowsFormsHost)) 
     { 
      FIELD_FOCUSED_CHILD.SetValue(host, null); 
     } 
    } 
} 


public readonly static FieldInfo FIELD_FOCUSED_CHILD = typeof(System.Windows.Forms.Integration.WindowsFormsHost). 
    GetField("_focusedChild", BindingFlags.NonPublic | BindingFlags.Instance); 

public static class DependencyObjectExtension 
{ 
    /// <summary> 
    /// Returns a collection of o's logical children, recursively. 
    /// </summary> 
    /// <param name="o"></param> 
    /// <returns></returns> 
    public static IEnumerable<DependencyObject> AllLogicalChildren(this DependencyObject o) 
    { 
     foreach (var child in LogicalTreeHelper.GetChildren(o)) 
     { 
      if (child is DependencyObject) 
      { 
       yield return (DependencyObject)child; 

       if (child is DependencyObject) 
       { 
        foreach (var innerChild in AllLogicalChildren((DependencyObject)child)) 
        { 
         yield return innerChild; 
        } 
       } 
      } 
     } 
    } 
} 
+0

Спасибо вам Шон, это полностью фиксирует – yunus

+0

я понял, что эта проблема фиксируется обновление или что-то. Кроме того, мы больше не можем получить '_focusedChild' частное поле. Кому нужно больше :) – yunus

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

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