2016-08-22 3 views
5

Я пытаюсь распечатать что-то из своего приложения UWP. В основном я использовал WebViewBrush, чтобы нарисовать некоторые данные на некотором FrameworkElement (Windows.UI.Xaml.Shapes.Rectangle) - и я хочу напечатать один из этих прямоугольников на каждой странице (один прямоугольник на странице)Как печатать в приложении UWP?

Я действительно надеялся, что кто-то может предоставить очень простой пример того, как работает печать в UWP. Я пробовал сам, и я рад предоставить свой код, но есть честно тысячи строк - все из которых я взял из примеров Microsoft GitHub и попытался настройки:

Честно говоря, эти примеры слишком сложны, я думаю. Я хочу просто очень простой способ печати. Я тоже не могу найти учебники по этой теме, но я полагаю, что если у кого-то есть небольшой фрагмент кода, который я мог бы получить, возможно, я мог бы построить его, поэтому он будет работать с Rectangles (а не тем, что я сейчас делаю) огромный пример от Microsoft и попытка выяснить, какие части мне не нужны).

спасибо. Я думаю, что любой, кто может ответить на этот вопрос простым способом, найдет, что это станет окончательной точкой отсчета в будущем, потому что информация в Интернете по этой теме настолько скудная.

ответ

8

Для печати в приложениях UWP вы можете выполнить шаги в Print from your app. А также обратитесь к Printing sample на GitHub. Ниже приведен простой пример, демонстрирующий, как печатать прямоугольник на странице.

В XAML добавьте кнопку печати и прямоугольник для печати.

<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> 

И в обратном порядке обрабатывайте логику печати.

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

Отличный пример! Примеры Microsoft слишком сложны. –

+0

Мне очень нравится ваш пример, однако, когда я нажимаю кнопку «Печать», я получаю это исключение: System.AccessViolationException: «Попытка чтения или записи защищенной памяти. Это часто свидетельствует о том, что другая память повреждена ». Эта ошибка возникает printDoc.SetPreviewPage. Я не могу найти решение этой проблемы, знаете ли вы, как ее решить. –

+0

@TravisPettry Я не могу воспроизвести вашу проблему на моей стороне. Вы можете попробовать протестировать некоторые другие устройства. Если у вас все еще есть эта проблема, я предлагаю вам задать новый вопрос с помощью [mcve], который может воспроизвести вашу проблему. –

1

Я тоже боролся с этим. Я перешел на пример SDK. Это решение может быть полезно для вас. Если есть способ, которым вы можете поместить то, что вы хотите распечатать, в RichTextBox, вы можете создавать абзацы для него программно. И замените RichTextBox в примере SDK пустой StackPanel, на которую вы указали требования к сетке, и это решит вашу проблему. Моя проблема была не совсем той же проблемой, потому что я сделал это с созданием 2-х столбчатых списков продуктов. Хитрость заключалась в использовании шрифта с фиксированной шириной CourierNew в моем примере.

В вашей странице, которая вызывает библиотеку печати, вы должны иметь это в XAML

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

На странице, которая заменяющий PageToPrint, вы можете построить этот материал прямо в конструкторе. Я передать коллекцию в конкретизацию страницы, а затем вычислить право макета в заменителе PageToPrint, как это ,,,

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); 
     } 
    } 

Это не совсем то, что вы ищете, но я знаю, как это тяжело найти что-то, что имеет смысл ответить на вопрос печати. Если вы хотите увидеть полный пример, то это мой проект GitHub.com/Gibbloggen GutenbergOne был моим прототипом, что я разработал этот материал. И я также импортировал в свой основной проект EssentialGrocer, это тоже с открытым исходным кодом в том же месте. Это, как раз сегодня, включает печать списка покупок.

Надеюсь, что это помогает, я действительно боролся с этим.

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