2016-08-22 17 views
5

Próbuję wydrukować coś z mojej aplikacji UWP. Zasadniczo użyłem WebViewBrush do narysowania niektórych danych do niektórych FrameworkElement (Windows.UI.Xaml.Shapes.Rectangle) - i chcę wydrukować jeden z tych prostokątów na każdej stronie (jeden prostokąt na stronę).Jak drukować w aplikacji UWP?

Naprawdę miałem nadzieję, że ktoś może dostarczyć bardzo prosty przykład jak działa druk w UWP. Próbowałem to sam i jestem zadowolony, aby zapewnić mojego kodu, ale istnieje naprawdę tysiące linii - z których wszystkie wziąłem z przykładów Microsoft GitHub i próbował szczypanie:

Szczerze mówiąc, te przykłady są zbyt skomplikowane, jak sądzę. To, czego chcę, to po prostu bardzo prosty sposób drukowania. Nie mogę też znaleźć żadnych tutoriali na ten temat, ale zdaję sobie sprawę, że jeśli ktoś ma mały fragment kodu, który mógłbym uruchomić, to mógłbym go zbudować, aby działał z Prostokątami (a nie tym, co robię teraz - biorąc pod uwagę ogromny przykład firmy Microsoft i próbujący dowiedzieć się, które części nie są mi potrzebne).

Dziękuję. Myślę, że każdy, kto może odpowiedzieć na to pytanie w prosty sposób, stwierdzi, że stanie się to ostatecznym punktem odniesienia w przyszłości - ponieważ informacje online na ten temat są tak rzadkie.

Odpowiedz

8

Aby dowiedzieć się, jak drukować w aplikacjach UWP, można wykonać kroki opisane w sekcji Print from your app. A także odnosić się do Printing sample na GitHub. Poniżej znajduje się prosty przykład ilustrujący sposób drukowania prostokąta na stronie.

W XAML, dodaj przycisk drukowania i prostokąt do wydrukowania.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition /> 
    </Grid.RowDefinitions> 
    <Button HorizontalAlignment="Center" Click="PrintButtonClick">Print</Button> 
    <Rectangle x:Name="RectangleToPrint" 
       Grid.Row="1" 
       Width="500" 
       Height="500"> 
     <Rectangle.Fill> 
      <ImageBrush ImageSource="Assets/img.jpg" /> 
     </Rectangle.Fill> 
    </Rectangle> 
</Grid> 

W kodowaniu z tyłu obsługujemy logikę drukowania.

public sealed partial class MainPage : Page 
{ 
    private PrintManager printMan; 
    private PrintDocument printDoc; 
    private IPrintDocumentSource printDocSource; 

    public MainPage() 
    { 
     this.InitializeComponent(); 
    } 

    #region Register for printing 

    protected override void OnNavigatedTo(NavigationEventArgs e) 
    { 
     // Register for PrintTaskRequested event 
     printMan = PrintManager.GetForCurrentView(); 
     printMan.PrintTaskRequested += PrintTaskRequested; 

     // Build a PrintDocument and register for callbacks 
     printDoc = new PrintDocument(); 
     printDocSource = printDoc.DocumentSource; 
     printDoc.Paginate += Paginate; 
     printDoc.GetPreviewPage += GetPreviewPage; 
     printDoc.AddPages += AddPages; 
    } 

    #endregion 

    #region Showing the print dialog 

    private async void PrintButtonClick(object sender, RoutedEventArgs e) 
    { 
     if (PrintManager.IsSupported()) 
     { 
      try 
      { 
       // Show print UI 
       await PrintManager.ShowPrintUIAsync(); 
      } 
      catch 
      { 
       // Printing cannot proceed at this time 
       ContentDialog noPrintingDialog = new ContentDialog() 
       { 
        Title = "Printing error", 
        Content = "\nSorry, printing can' t proceed at this time.", 
        PrimaryButtonText = "OK" 
       }; 
       await noPrintingDialog.ShowAsync(); 
      } 
     } 
     else 
     { 
      // Printing is not supported on this device 
      ContentDialog noPrintingDialog = new ContentDialog() 
      { 
       Title = "Printing not supported", 
       Content = "\nSorry, printing is not supported on this device.", 
       PrimaryButtonText = "OK" 
      }; 
      await noPrintingDialog.ShowAsync(); 
     } 
    } 

    private void PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args) 
    { 
     // Create the PrintTask. 
     // Defines the title and delegate for PrintTaskSourceRequested 
     var printTask = args.Request.CreatePrintTask("Print", PrintTaskSourceRequrested); 

     // Handle PrintTask.Completed to catch failed print jobs 
     printTask.Completed += PrintTaskCompleted; 
    } 

    private void PrintTaskSourceRequrested(PrintTaskSourceRequestedArgs args) 
    { 
     // Set the document source. 
     args.SetSource(printDocSource); 
    } 

    #endregion 

    #region Print preview 

    private void Paginate(object sender, PaginateEventArgs e) 
    { 
     // As I only want to print one Rectangle, so I set the count to 1 
     printDoc.SetPreviewPageCount(1, PreviewPageCountType.Final); 
    } 

    private void GetPreviewPage(object sender, GetPreviewPageEventArgs e) 
    { 
     // Provide a UIElement as the print preview. 
     printDoc.SetPreviewPage(e.PageNumber, this.RectangleToPrint); 
    } 

    #endregion 

    #region Add pages to send to the printer 

    private void AddPages(object sender, AddPagesEventArgs e) 
    { 
     printDoc.AddPage(this.RectangleToPrint); 

     // Indicate that all of the print pages have been provided 
     printDoc.AddPagesComplete(); 
    } 

    #endregion 

    #region Print task completed 

    private async void PrintTaskCompleted(PrintTask sender, PrintTaskCompletedEventArgs args) 
    { 
     // Notify the user when the print operation fails. 
     if (args.Completion == PrintTaskCompletion.Failed) 
     { 
      await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => 
      { 
       ContentDialog noPrintingDialog = new ContentDialog() 
       { 
        Title = "Printing error", 
        Content = "\nSorry, failed to print.", 
        PrimaryButtonText = "OK" 
       }; 
       await noPrintingDialog.ShowAsync(); 
      }); 
     } 
    } 

    #endregion 
} 
+1

Świetny przykład! Przykłady Microsoftu są zbyt skomplikowane. –

+0

Bardzo podoba mi się twój przykład, jednak gdy klikam przycisk drukowania, otrzymuję ten wyjątek: System.AccessViolationException: "Próba odczytu lub zapisu pamięci chronionej. Często jest to wskazówką, że inna pamięć jest uszkodzona ". Ten błąd występuje printDoc.SetPreviewPage. Nie mogę znaleźć rozwiązania tego problemu, czy wiesz, jak go rozwiązać. –

+0

@TravisPettry Nie mogę odtworzyć Twojego problemu po mojej stronie. Możesz spróbować przetestować na kilku innych urządzeniach. Jeśli nadal masz ten problem, proponuję zadać nowe pytanie z [mcve], które może odtworzyć twój problem. –

1

Ja też zmagałem się z tym. Przeszukałem przykład SDK. To rozwiązanie może ci się przydać. Jeśli istnieje sposób, w jaki możesz umieścić to, co chcesz wydrukować w RichTextBox, możesz programowo budować dla niego akapity. I zamień RichTextBox w przykładzie SDK z pustym StackPanel, na którym masz określone wymagania sieci, i to rozwiąże twój problem. Mój nie był dokładnie ten sam problem, ponieważ zrobiłem to z Tworzenie nawet 2 kolumnowej listy zakupów. Sztuką było użycie w moim przykładzie czcionki o stałej szerokości CourierNew.

na swojej stronie, która wymaga bibliotek drukowania, trzeba mieć to w XAML

<Canvas x:Name="PrintCanvas" Opacity="0"/>

Na stronie, która jest zastępującego PageToPrint można budować te rzeczy prawo w konstruktorze. Mijam kolekcję do instancji strony, a następnie obliczyć prawo układu w zastępstwie PageToPrint, jak to ,,,

private void MakeThePrintOut() 
    { 


     RichTextBlock gutOne = initBlock(); 
     PopulateBlock(gutOne); 
     ContentStack.Children.Add(gutOne); 


    } 
    private RichTextBlock initBlock() 
    { 

     RichTextBlock gutInitBlock = new RichTextBlock(); 
     gutInitBlock.Foreground = new SolidColorBrush(Windows.UI.Colors.Black); 
     gutInitBlock.FontSize = 18; 
     gutInitBlock.OverflowContentTarget = FirstLinkedContainer; 
     gutInitBlock.FontFamily = new FontFamily("Courier New"); 
     gutInitBlock.VerticalAlignment = VerticalAlignment.Top; 
     gutInitBlock.HorizontalAlignment = HorizontalAlignment.Left; 
     return gutInitBlock; 

    } 
    private void PopulateBlock(RichTextBlock Blocker) 
    { 


     bool firstItem = true; 
     int firstLength = 0; 
     Paragraph paraItem = null; 
     Run itemRun = null; 

     string CurrentIsle = "None"; 

     foreach(Grocery j in Grocs) 
     { 
      if (j.Isle != CurrentIsle) 
      { 
       if ((CurrentIsle != "None") && (!firstItem)) 
       { 
        paraItem.Inlines.Add(itemRun); 
        Blocker.Blocks.Add(paraItem); 

       } 
       CurrentIsle = j.Isle; 
       firstItem = true; 
       Paragraph paraIsle = new Paragraph(); 
       Run paraRan = new Run(); 
       paraRan.Text = "  " + j.Isle; 
       paraIsle.Inlines.Add(paraRan); 
       Blocker.Blocks.Add(paraIsle); 


      } 
      if (firstItem) 
      { 
       paraItem = new Paragraph(); 
       itemRun = new Run(); 
       itemRun.Text = "  [] " + j.Item; 
       firstLength = j.Item.Length; 
       firstItem = false; 
      } else 
      { 
       firstItem = true; 
       string s = new string(' ', 30 - firstLength); 
       itemRun.Text += s + "[] " + j.Item; 
       paraItem.Inlines.Add(itemRun); 
       Blocker.Blocks.Add(paraItem); 

      } 





      } 
     if (!firstItem) 
     { 
      paraItem.Inlines.Add(itemRun); 
      Blocker.Blocks.Add(paraItem); 
     } 
    } 

To nie jest dokładnie to, czego szukasz, ale wiem, jak trudno jest znaleźć coś, co ma sens, aby odpowiedzieć na pytanie o druk. Jeśli chcesz zobaczyć pełny przykład, który jest na moim GitHub.com/Gibbloggen, projekt GutenbergOne to moje prototypowanie, że opracowałem to. I również zaimportowałem do mojego głównego projektu EssentialGrocer, to także jest open source w tej samej lokalizacji. To, właśnie dziś wieczorem, obejmuje drukowanie listy zakupów.

Mam nadzieję, że niektóre z nich pomagają, naprawdę zmagałem się z tym również.

Powiązane problemy