Makale Özeti

WPF ile uygulama geliştirirken belki de hissettiğimiz en büyük eksik Winforms'dan alışık olduğumuz kontrolleri WPF tarafında kullanamıyor olmamız veya muadillerinin hali hazırda bulunmuyor olması. İşte bu yazımızda WPF uygulamalarında Winforms kontrolleri kullanmanın yolunu inceleyeceğiz.

Makale

Daha önceki bir yazımda WPF özelliklerini Winforms pencerelerine nasıl taşıyabileceğimizden bahsetmiştim. Oysa bir de tam tersi bir senaryo da mümkün olabilir. Yani Winforms tarafındaki bir kontrolü herhangi bir WPF uygulamasına kullanmak isteyebilirsiniz. Peki bu durumda neler yapabilirz? İşte bu yazımızda bu sorunu çözeceğiz.

Winforms kontrollerini WPF projemize ekleyelim.

İlk olarak yarattığımız herhangi bir WPF projesinde Winforms kontrollerini kullanabilmek için tabi ki System.Windows.Forms namespace'ini projemize referans olarak eklememiz gerekiyor. Ayrıca Winforms kontrolleri ile WPF uygulaması arasında aracı görevi görecek olan WindowsFormsHost sınıfının da projeye kesinlikle referans olarak eklenmesi şart.

WPF projemizde Winforms kontrolleri kullanabilmek için eklediğimiz referanslar.
WPF projemizde Winforms kontrolleri kullanabilmek için eklediğimiz referanslar.

Yukarıdaki ekran görüntüsünde de görebileceğiniz üzere biri .NET Framework 2.0'dan diğeri de 3.0'dan iki farklı harici sınıfı projemize referans olarak eklememiz gerekiyor. Sonrasında artık yazacağımız kodlar ile uygulamamızda Winforms kontrollerini kullanabileceğiz.

Kod ile Winforms kontrollerinin WPF içerisinde kullanımı

Gelin hemen bir örnek deneyelim ve ufak bir WPF uygulaması hazırlayarak içerisine de minik bir animasyon yerleştirelim. Sonrasında hedefimiz bu WPF uygulamasına bir Winforms Button kontrolü yerleştirerek düğmeye basıldığında WPF animasyonunu çalıştırmak olsun.

<Window

  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/psentation"

  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  x:Class="Window1"

  x:Name="Window"

  Title="Window1"

  Width="640" Height="480">

  <Window.Resources>

    <Storyboard x:Key="Animasyon">

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Rectangle.RadiusX)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:01" Value="99"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="0"/>

      </DoubleAnimationUsingKeyFrames>

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Rectangle.RadiusY)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:01" Value="99"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="0"/>

      </DoubleAnimationUsingKeyFrames>

    </Storyboard>

  </Window.Resources>

  <Grid x:Name="LayoutRoot">

    <Rectangle HorizontalAlignment="Left" Margin="46,80,0,0" VerticalAlignment="Top" Width="199" Height="137" Fill="#FFFF0000" Stroke="#FF000000" x:Name="rectangle"/>

    <Canvas Margin="96,0,295,70" VerticalAlignment="Bottom" Height="118" x:Name="WinformsCanvas"/>

  </Grid>

</Window>

Gördüğünüz gibi kod içerisinde animasyon uygulanan bir dikdörtgen ve bir de Canvas bulunuyor. Söz konusu Canvas'ın adı da WinformsCanvas olarak düzenlenmiş. İşte biz de Winforms kontrolümüzü tam bu Canvas'ın içerisine kod ile ekleyeceğiz.

    Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        Dim HostKontrol As New System.Windows.Forms.Integration.WindowsFormsHost

        Dim x As New System.Windows.Forms.Button

        x.Text = "Deneme"

        AddHandler x.Click, AddressOf Tiklandi

        HostKontrol.Child = x

        WinformsCanvas.Children.Add(HostKontrol)

    End Sub

 

    Private Sub Tiklandi(ByVal sender As Object, ByVal e As EventArgs)

        CType(Me.Resources("Animasyon"), Storyboard).Begin(Me)

    End Sub

Gördüğünüz gibi ilk olarak bir WindowsFormsHost kontrolü yaratıyoruz. Bu kontrol herhangi bir Winforms kontrolünün WPF uygulamasına kullanılabilmesini sağlıyor. Biz örnek olarak bir düğme yaratarak HostKontrol değişkenine bunu aktarıyoruz. Son olarak da XAML kodumuzdaki Canvas'ın içerisinde WindowsFormsHost kontrolümü yerleştiriyoruz. Kod içerisinde yarattığımız düğmenin Click durumun da başka bir handler ile yakaladığımız için rahatlıkla istediğimiz WPF animasyonunu yakalayarak çalıştırabiliriz. Tabi hikaye sadece standart Winforms kontrolleri için geçerli değil, isterseniz Winforms uygulamalarında UserControl'lerinizi de aynı şekilde kullanabilirsiniz.

XAML ile Winforms kontrollerinin WPF içerisinde kullanımı

Peki doğrudan XAML içerisinde Winforms kontrollerini kullanmak istersek neler yapabiliriz? Böyle bir durumda da doğrudan XAML içerisinde söz konusu sınıfları tanımlamış olmanız gerekecektir.

  xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"

  xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

Yukarıdaki gibi gerekli tanımlamaları yaptıktan sonra artık ister doğrudan WindowsFormsHost kontrolünü ister herhangi bir Winforms kontrolünü XAML içerisinde rahatlıkla kullanabilirsiniz.

<Window

  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/psentation"

  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"

  xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

  x:Class="Window1"

  x:Name="Window"

  Title="Window1"

  Width="640" Height="480">

  <Window.Resources>

    <Storyboard x:Key="Animasyon">

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Rectangle.RadiusX)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:01" Value="99"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="0"/>

      </DoubleAnimationUsingKeyFrames>

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Rectangle.RadiusY)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:01" Value="99"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="0"/>

      </DoubleAnimationUsingKeyFrames>

    </Storyboard>

  </Window.Resources>

  <Window.Triggers>

  </Window.Triggers>

 

  <Grid x:Name="LayoutRoot">

    <Rectangle HorizontalAlignment="Left" Margin="46,80,0,0" VerticalAlignment="Top" Width="199" Height="137" Fill="#FFFF0000" Stroke="#FF000000" x:Name="rectangle"/>

    <Canvas Margin="96,0,295,70" VerticalAlignment="Bottom" Height="118" x:Name="WinformsCanvas">

    <WindowsFormsHost>

      <wf:Button Text="Tikla" Click="Tiklandi"/>

    </WindowsFormsHost>

    </Canvas>

  </Grid>

</Window>

Düğmemizin code-behind kısmına baktığımızda aslında standart bir event-handler'dan farklı birşey de görmüyoruz.

    Private Sub Tiklandi(ByVal sender As Object, ByVal e As EventArgs)

        CType(Me.Resources("Animasyon"), Storyboard).Begin(Me)

    End Sub

Böylece Winforms kontrolümüzü WPF içerisinde rahatlıkla kullanabiliyoruz. Özellikle WPF kontrolleri arasında şu an eksik olan çoğu Winforms kontrolünü bu şekilde WPF dünyasına alarak söz konusu kontrollerin işlevselliklerinden faydalanabiliriz.

Hepinize kolay gelsin.

Daron Yöndem
MVP, MCT, MCPD, MCITP, MCTS
MCSD, MCAD, MCDBA, MCP, ACP, ICSD
http://daron.yondem.com