Ahmet Çığşar | WPF’de Yazdırma (Print) ve Önizleme (Print Preview) İşlemleri
642
post-template-default,single,single-post,postid-642,single-format-standard,qode-quick-links-1.0,ajax_fade,page_not_loaded,,qode-theme-ver-11.0,qode-theme-bridge

WPF’de Yazdırma (Print) ve Önizleme (Print Preview) İşlemleri

WPF’de Yazdırma (Print) ve Önizleme (Print Preview) İşlemleri

Uygulamalarımız hangi sektöre, hangi amaca hitap ederse etsin genellikle yazdırma işlemlerine ihtiyaç duyulur. Bu ihtiyaç PDF Printer, XPS Printer veya Image Printer gibi sanal yazıcı uygulamalarının kullanımlarındaki artışla daha da fazla ihtiyaç haline geldi. Peki WPF arayüzlerinde yazdırma işlemlerini ve önizleme işlemlerini nasıl yapacağız?

Önemli : Bu yazı için hazırladığım örnek uygulamanın linkini makalenin sonunda bulabilirsiniz. İndirip inceleyebilirsiniz. Uygulamada kodlar arasında yorumlar ekledim, umarım yardımcı olur.

PrintDialog ile WPF’de Yazdırma İşlemleri

WPF’de direkt yazdırma işlemlerini PrintDialog sınıfı ile yaparız. Direkt yazdırma diyorum çünkü bu karşımıza bir önizleme penceresi açmadan direkt yazdırma penceresini çıkartacaktır. Önizleme nasıl yapılır onuda öğreneceğiz birazdan.

1. Visual Studio ile WPF uygulaması açalım. Karşımıza çıkan ana pencerenin (MainWindow) XAML alanına giderek Grid etiketini silip aşağıdaki kodları yapıştıralım.

    <Grid x:Name="anaAlan">
        <Label Content="Soyadınız *" HorizontalAlignment="Left" Margin="16,99,0,0" VerticalAlignment="Top" Width="92"/>
        <TextBlock HorizontalAlignment="Left" Margin="23,21,0,0" TextWrapping="Wrap" Text="Lütfen aşağıdaki başvuru formunu eksiksiz ve doğru bilgilerle doldurun." VerticalAlignment="Top" Width="465" Foreground="#FF232222" TextDecorations="{x:Null}" FontSize="14"/>
        <Label Content="Adınız *" HorizontalAlignment="Left" Margin="16,70,0,0" VerticalAlignment="Top" Width="92"/>
        <Label Content="Cinsiyetiniz *" HorizontalAlignment="Left" Margin="16,127,0,0" VerticalAlignment="Top" Width="92"/>
        <Label Content="e-Posta *" HorizontalAlignment="Left" Margin="16,153,0,0" VerticalAlignment="Top" Width="92"/>
        <Label Content="Telefon&#x9;" HorizontalAlignment="Left" Margin="16,179,0,0" VerticalAlignment="Top" Width="92"/>
        <Label Content="Eklemek İstedikleriniz" HorizontalAlignment="Left" Margin="16,218,0,0" VerticalAlignment="Top" Width="127"/>
        <TextBox HorizontalAlignment="Left" Height="103" Margin="23,249,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="471"/>
        <TextBox x:Name="txtAdiniz" HorizontalAlignment="Left" Height="23" Margin="113,70,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="150"/>
        <TextBox x:Name="txtSoyadiniz" HorizontalAlignment="Left" Height="23" Margin="113,99,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="150"/>
        <ComboBox x:Name="cbxCinsiyet" HorizontalAlignment="Left" Margin="113,127,0,0" VerticalAlignment="Top" Width="150">
            <ComboBoxItem Content="Erkek"/>
            <ComboBoxItem Content="Kadın"/>
        </ComboBox>
        <TextBox x:Name="txtEposta" HorizontalAlignment="Left" Height="23" Margin="113,154,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="150"/>
        <TextBox x:Name="txtTelefon" HorizontalAlignment="Left" Height="23" Margin="113,182,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="150"/>
        <Button x:Name="btnBasvur" Content="Başvuruyu Gönder" HorizontalAlignment="Left" Margin="381,380,0,0" VerticalAlignment="Top" Width="111"/>
        <Button x:Name="btnYazdir" Content="Yazdır" HorizontalAlignment="Left" Margin="316,380,0,0" VerticalAlignment="Top" Width="60" Click="btnYazdir_Click"/>
        <Button x:Name="btnOnizleme" Content="Önizleme" HorizontalAlignment="Left" Margin="236,380,0,0" VerticalAlignment="Top" Width="75" Click="btnOnizleme_Click"/>
    </Grid>

Grid’in adının anaAlan olduğuna dikkat edin lütfen. Ayrıca butonlarında x:Name özelliklerine gözgezdirmenizde fayda var.

Yukarıdaki kodları yapıştırdıktan sonra aşağıdaki görüntüyü elde etmeniz lazım. Eğer pencere ufak kalıyorsa  Properties penceresinden veya XAML alanından pencerenin Height ve Width özelliklerine biraz yüksek değer verin lütfen.

wpf_basvuru_form2- Yazdır butonuna çift tıklıyor ve Click event’ine gidiyoruz. Aşağıdaki kodları yazıyoruz.

        private void btnYazdir_Click(object sender, RoutedEventArgs e)
        {
            PrintDialog formuYazdir = new PrintDialog();

            if (formuYazdir.ShowDialog() == true)
            {
                formuYazdir.PrintVisual((anaAlan), "Form Çıktısı");
            }

            else
            {
                MessageBox.Show("Hiç seçim yapılmadı. Bilginize.");
            }

        }

– formuYazdir adında bir PrintDialog nesnesi yani yazdırma işlemlerini getiren pencereyi oluşturuyoruz.
– if ile formu yazdır penceresinin açılıp seçim yapıp yapılmadığını kontrol ediyoruz.
– anaAlan adını verdiğimiz gridimizi PrintVisual metodunun kollarına atıyoruz bu şu demek anaAlan adlı etiketin içerisindekileri yazdıracağız anlamına gelir. “Form Çıktısı” yazısı ise yazdırılan dosyanın adıdır. Dilediğinizi yazabilirsiniz. İsterseniz Adınız ve Soyadınız TextBox kontrollerindeki verileri alıp çıktı başlığı olarak kullanabilirsiniz. Hayal gücünüze kalmış.
– else durumunu yazmasanızda olur ama ben yazmak istedim.

Şimdi uygulamamızı çalıştırıp Yazdır butonuna tıkladığınızda aşağıdaki gibi bir pencere açılacaktır.

yazici_listesi

WPF’de Yazdırma Öncesi Önizleme (PrintPreview) Yapımı

Malesef WPF’de PrintPreview işlemini yerine getirmek için özel olarak hazırlanmış bir nesne yok . Öncelikle bu işlemi kendi oluşturacağınız sınıflar ve metodlar ile yapabilirsiniz. Ayrıca sırf yazdırma ve önizleme için yazılmış kontroller var (Ör: RadDiagramPrintPreview, WPF PrintPreview Engine… gibi) dilerseniz onlarıda kullanabilirsiniz ama uygulamanızda önizleme için ufak bir hileyle kendi önizleme penceremizi oluşturabiliriz. PrintPreview için nesne yok diye üzülmek yok. Yaparız olur.

1- Yazdırma Önizlemesi (PrintPreview) işleminde kullanmak için projemize yeni bir Window ekliyoruz ve adını OnIzleme yapıyoruz ve aşağıdaki minik kodu yeni Window’umuzun XAML alanına yapıştırıyoruz. Gördüğünüz gibi DocumentViewer nesnesi eklemişiz ve adını XpsOkuyu yapmışız.

    <Grid>
        <DocumentViewer  x:Name="XpsOkuyucu" />
    </Grid>

2- OnIzleme penceresindeyken F7’ye basıyoruz ve kod kısmına geçiyoruz aşağıdaki gibi kodlarımızı yazıyoruz. Kodların InitializeComponent(); kod satırından sonra geldiğine dikkat edin. Aksi halde pencere ya açılamayacak ya da açılsa bile her tarafı gri olan bir pencere açılacaktır.

    public partial class OnIzleme : Window
    {
        public OnIzleme()
        {
            InitializeComponent();

            XpsDocument okunacakBelge = new XpsDocument(@"C:Temponizleme.xps", FileAccess.Read);
            XpsOkuyucu.Document = okunacakBelge.GetFixedDocumentSequence();
        }
    }

Buradaki espri şu: MainWindow’da bulunan Önizleme butonuna tıklandığında arkaplanda bir onizleme.xps dosyası oluşturacak, dosya oluştuktan sonra OnIzleme adlı yukarıdaki penceremiz açılacak ve arkaplanda oluşturduğumuz onizleme.xps dosyasını ekranda gösterecek. Kurnazca bir çözüm olsada en pratik çözümdür. Sonuçta önizleme.

Burada dikkat etmeniz gereken, ben Temp klasörü oluşturup adres gösterdim eğer Temp adında klasörünüz yoksa uygulama hata verecektir. Bu durumu tabi if ve System.IO sınıfından Directory işlemlerini kullanarak engelleyebilirdik, öyle bir klasör yoksa oluştur diyebilirdik veya sistem tempory kullan diyebilirdik ama konumuz dışında.

Yine bura için önemli son bir not: Kod karmaşası olmaması için onizleme.xps adında bir belge oluşturmasını istedim burada önemli olan oluşan dosyayı diğer pencere tarafında aynı isimle yakalayıp gösterebilmek. Dosya adı sürekli değişecek bir yapıda olabilir ve buna göre bir önlem almanız gerekebilir. Hatırlatmakta fayda var.

3- Şimdi tekrar MainWindow’umuza dönüyoruz ve Önizleme butonumuza çift tıklayarak Click eventine gidiyoruz ve aşağıdaki C# kodlarını yazıyoruz.

private void btnOnizleme_Click(object sender, RoutedEventArgs e)
        {
            Package onizlemeBilgiler = Package.Open(@"C:Temponizleme.xps", FileMode.Create);

            XpsDocument onizleme = new XpsDocument(onizlemeBilgiler);

            XpsDocumentWriter xpsYazici = XpsDocument.CreateXpsDocumentWriter(onizleme);

            xpsYazici.Write(anaAlan);

            onizleme.Close();
            onizlemeBilgiler.Close();

            OnIzleme ac = new OnIzleme();
            ac.Show();
        }

Yukarıdaki kodları aşağıda satır satır açıklayalım.

//Package sınıfından onizlemeBilgiler adında nesne oluşturuyoruz ve bu nesneye kayıt yerini ve ne yapacağını belirtiyoruz. 
//Package nesnesi zaten bunun içindir.
Package onizlemeBilgiler = Package.Open(@"C:Temponizleme.xps", FileMode.Create);
//onizleme adında Xps nesnesi oluşturuyoruz ve gerekli bilgileri oluşturduğumuz 
//onizlemeBilgiler adlı Package nesnesinden alıyoruz.
XpsDocument onizleme = new XpsDocument(onizlemeBilgiler);
//xpsYazici adında Xps yazıcı nesnesi oluşturuyoruz ve 
//hangi dökümanı baz alacağını (onizleme) belirtiyoruz
XpsDocumentWriter xpsYazici = XpsDocument.CreateXpsDocumentWriter(onizleme);
//anaAlan adlı grid nesnemizi baz almasını ve bu nesne içerisinde olan her şeyi yazdırmasını istiyoruz.
xpsYazici.Write(anaAlan);
//Artık xps oluşturma işimiz bitti ve package nesnemizle dökümanımızı kapatmamız lazım.
            onizleme.Close();
            onizlemeBilgiler.Close();
//Solution Explorer içerisinde bulunan önceden oluşturduğumuz 
//OnIzleme adlı pencereden bir nesne oluşturuyoruz ve Show() metodu ile gösteriyoruz.
            OnIzleme ac = new OnIzleme();
            ac.Show();

Önizleme penceresinin görüntüsü:

printpreview_onizleme

[wpdm_file id=10]
15 Yorum Var
  • Agop Markaryan
    11:42h, 02 Mart Cevapla

    WPF arayüzünde printpreview yaptırmak için kırk takla atmıştım. Ne eklentiler kütüphaneler indirmiştim şimdi tekrar lazım oldu ve acaba yeni bir şeyler var mı diyerek ararken yazınızı gördüm çok işime yaramakla ve zaman kazandırmakla birlikte bu makalenin zamanla en çok okunanlar listesine gireceğine eminim 🙂

    • Ahmet Çığşar
      19:19h, 02 Mart Cevapla

      Öncelikle teşekkürler. Print işlemi basit gibi görünsede WPF’de uygulaması Windows Forms’daki kadar kolay değil maalesef. Zamanında aynı sorunları yaşamış biri olarak bende paylaşmak istedim 🙂

  • Ozan
    11:43h, 13 Haziran Cevapla

    Merhaba Ahmet bey,

    peki senaryoyu şu şekilde değiştirsem ? textboxlara girilen , combolardan seçilen alanları world dökümanına belli bir formatta yazdırmam için nasıl bir yol izlemem gerekir ?

    teşekkürler.

    • Ahmet Çığşar
      22:42h, 16 Haziran Cevapla

      Merhabalar Ozan Bey,

      Word formatında yazdırmak veya hazırdaki bir Word dosyasına verileri yazdırma basit gibi görünsede detayları fazla olan bir konu. Sizin yorumunuzdan sonra bu konuyla ilgili ayrıca bir makale yazmak istiyorum. Kısaca değinmem gerekirse. Bunu yapmanın farklı yöntemleri var fakat iş C# tarafında bitiyor. Projenizin referanslarına “Microsoft Office Object Library” ve “Microsoft Word Object Library” eklemeniz gerekli. Ardından Word.Application ve Word.Document Class kullanmanız gerekli. Özetin özetinin özeti böyle 🙂 Dediğim gibi detaylar fazla ama anahatlar böyle. Ana hatları internetten araştırarak detaylara ulaşabilirsiniz.

  • İlhan Kaya
    15:33h, 28 Ağustos Cevapla

    Merhaba, öncelikle bu çalışma için teşekkür ederim.
    VS2012 kullanıyorum ve XpsDocument’i kullanmamı sağlayacak referansları ve classları bulamadım bir türlü yardımcı olabilir misiniz ?

  • ugur
    19:04h, 02 Aralık Cevapla

    merhaba peki birde c# da datagrid den seçilen hücrelere göre A4 sayfaya yazdırma işlemleri nasıl yapılır her seçilen hücreyi başka bir sayfada yazdırmak nasıl yapılır bir örnek yaparsanız sevinirm.2 haftadır takılı kaldım 🙁

    • Ahmet Çığşar
      22:11h, 05 Aralık Cevapla

      Selamlar,
      Şu aralar taslak halindeki makalelerimi bile tamamlayıp yayınlayacak zamanı bulamıyorum ama yazmaya çalışacağım. Yinede söz veremem.

  • basaroztas
    18:17h, 19 Aralık Cevapla

    Selamlar benim sorunum WPF’de yazdırmayı PDF olarak kaydettikten sonra benim pc de görüntü normal fakat başka bilgisayardan PDF olarak kaydetmeye kalktığımda locasyonda bozulmalar oluyor düzgün çıkmıyor bunu nasıl çözebilirim C#’da böyle bir sorun meydana gelmiyordu

    • Ahmet Çığşar
      23:07h, 03 Ocak Cevapla

      Karşılaştığınız sorunu tam olarak anlayamadım ama büyük ihtimalle karakter hataları gibi ise ilgili bilgisayarın dil ve lokasyon ayarları, pdf programının karakter kodlaması buna sebep olabilir ama bahsi geçen yazdırılan alanın grafikleri ve diğer nesneler ise izlenecek yollar daha farklıdır.

  • Sehmuz Altın
    11:48h, 15 Eylül Cevapla

    malesef dosya indirme linkinde hata var.

    • Ahmet Çığşar
      14:30h, 16 Eylül Cevapla

      Şehmuz selam,

      Geribildirimin için çok teşekkür ediyorum. Hata düzeltildi, artık indirebilirsin.

  • Sinan Can Aydın
    19:35h, 16 Aralık Cevapla

    elinize sağlık
    indirme linkini göremedim tekrar link verebilirmisiniz acaba

  • Mehmet
    08:27h, 28 Mart Cevapla

    Elinize sağlık çok güzel bir çalışma olmuş. Tek sorun Pc de OneNote yüklü olması gerekiyor galiba.

    • Ahmet Çığşar
      00:42h, 01 Nisan Cevapla

      Merhaba, hayır OneNote ile herhangi bir ilgisi yok. Çok kısa bir cevap oldu ama 🙂

Yorum Yapın