niedziela, 19 czerwca 2011

70-511: Enhancing Usability: Integrowanie Windows Forms i WPF w jednej aplikacji (teoria) [PL]

W ramach mojego przygotowania do egzaminu 70-511 (Windows Applications Development with Microsoft .NET Framework 4) oraz uczestnictwa w „StudyGroup” organizowanym przez Łódzką Grupę Profesionalistów IT & .NET opracowałem zagadnienia związane z tematem określonym w training kicie jako „Enhancing Usability”. Z moimi czytelnikami chciałbym podzielić się moimi opracowaniami. W tym wpisie będzie o jednoczesnym wykorzystaniu i integracji Windows Forms i WPF w jednej aplikacji.
Zacznijmy może od stwierdzenia faktu, że nie wszystkie kontrolki znane z Windows Forms są w aplikacjach WPF (brakuje np. MaskedTextBox lub PropertyGrid), choć w większości przypadków dostępne są odpowiedniki. W związku z powyższym może zajść potrzeba wykorzystania kontrolek Windows Forms wewnątrz aplikacji WPF. Wystąpić również odwrotna sytuacja, czyli potrzeba osadzenia kontrolki WPF w oknie aplikacji Windows Forms (np. w aplikacji bazującej na Windows Forms chcielibyśmy wyświetlać trójwymiarowe kształty bazujące na WPF 3D).

Wykorzystanie podstawowych okien dialogowych w aplikacji WPF

Na początku warto zauważyć, że bez problemu można używać podstawowych okien dialogowych z poziomu aplikacji WPF (np. OpenFileDialog, SaveFileDialog, FolderBrowserDialog, ColorDialog, FontDialog, PrintDialog, PageSetupDialog, itp...). Stwierdzenie to jest chyba dość oczywiste, ale (jak to sugeruje Training Kit) warto o tym wspomnieć w tym kontekście.
Poniżej przedstawiono przykład wyświetlenia okienka do wyboru pliku po naciśnięciu przycisku w WPF:
private void button_open_file_dialog_Click( object sender, RoutedEventArgs e )
{
  using ( var ofd = new System.Windows.Forms.OpenFileDialog() )
    ofd.ShowDialog();
}

Windows Forms w WPF, czyli WindowsFormsHost

System.Windows.Forms.Integration.WindowsFormsHost (z WindowsFormsIntegration.dll) jest elementem (kontrolką) WPF pozwalającą na osadzenie pojedynczego elementu będącego kontrolką Windows Forms. Hostowana kontrolka Windows Forms jest automatycznie dopasowywana do rozmiaru kontrolki nadrzędnej (WindowsFormsHost). Można używać WindowsFormsHost do deklaratywnego (z poziomu XAML) tworzenia instancji kontrolek Windows Forms i również ustawiania ich właściwości w sposób deklaratywny.
W praktyce wykorzystanie z WindowsFormsHost w WPF sprowadza się do:
  1. Dodania namespaces'ów (podane nazwy „my” i „wf” są oczywiście przykładowe – ważne jest to, co występuje po „=”):
  • xmlns:my="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
  • xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
  1. Dodania WindowsFormsHost i elementu z Windows Forms, np.:
<my:WindowsFormsHost Margin="48,106,30,56" Name="windowsFormsHost1">
  <wf:Button Text="Windows Forms Button" />
</my:WindowsFormsHost>
Zwróćmy tutaj uwagę, że właściwości kontrolki Windows Forms są ustawiane deklaratywnie, tak samo jak dla elementów WPF w XAML.
Warto też wiedzieć, że możemy uzyskać referencję od osadzonego elementu Windows Forms poprzez właściwość Child, np.: System.Windows.Forms.Button aButton; aButton = (System.Windows.Forms.Button)windowsFormsHost1.Child;.

WPF wewnątrz Windows Forms, czyli ElementHost

Kontrolka System.Windows.Forms.Integration.ElementHost w Windows Forms pozwala na osadzanie kontrolek WPF wewnątrz okna aplikacji Windows Forms. Kontrolka WPF jest podstawiana do właściwości Child obiektu klasy ElementHost, np.:
WPFProject.UserControl1 aWPFcontrol = new WPFProject.UserControl1;
ElementHost1.Child = aWPFcontrol;
Promuj

3 komentarze:

  1. szczerze powiedziawszy ten "feature" osadzania kontrolek WindowsForms w WPF'ie chyba mało komu się przydaje (z profesjonalnym podejściem do kodowania), albowiem "wszystko" to co jest w WinForm można osiągnąć również w WPI'ie. Jakkolwiek, na egzaminie 70-511 miałem jedno pytanie odnośnie ElementHost.

    OdpowiedzUsuń
  2. Witam,
    W większości przypadków masz rację chociaż zauważ, że czasem:
    - nie masz pełnej swobody i np. w poprzedniej wersji projektu była zaawansowana, "czego to nie robiąca" kontrolka WinForms, nie ma czasu i budżetu na jej przepisanie, więc ją po prostu osadzasz.
    - nie wszystkie kontrolki z WinForms są w WPF'ie np. czemu tworzyć od nowa kontrolkę PropertyGrid? (nie zawsze wolno Ci użyć opensource'owych http://wpfpropertygrid.codeplex.com/ czy http://wpg.codeplex.com/)

    Dlatego (poza możliwością padnięcia pytania na egzaminie) wiedzieć o możliwości integracji.

    Pozdrawiam.

    OdpowiedzUsuń
  3. zgadzam się z Twoimi argumentami, tak jak pisałem "wszystko" da się osiągnąć w WPF'ie to co w WinForms, jak również, że kontrolka tak MAŁO się przydaje i jest używana ;). Nie piszę, że jest zbędna. Dodatkowo wydaje mi się, że dopełnieniem artukułu mogłoby być mapowanie właściwości: http://msdn.microsoft.com/en-us/library/ms788740.aspx

    OdpowiedzUsuń

Posty powiązane / Related posts