【问题标题】:Error when setting a PrintDialog's PrintQueue to a networked printer - C# WPF XAML将 PrintDialog 的 PrintQueue 设置为联网打印机时出错 - C# WPF XAML
【发布时间】:2020-11-10 20:42:58
【问题描述】:

我正在尝试设置 WPF PrintDialog 以使用用户在表单上设置的值来控制基本打印选项,而不是向它们显示对话框。

目标是让他们一次性设置打印选项,然后在一天中使用这些设置数百次,除非他们决定这样做,否则无需更改它们。

该代码适用于我机器上安装的所有打印机,网络打印机除外。如果我从列表中选择联网打印机,我会收到以下错误 -

System.Printing.PrintQueueException: '填充 PrintQueue 对象的属性时发生异常。 Win32 错误:打印机名称无效。'

奇怪的是,如果我将其中一台网络打印机设置为默认打印机,并添加逻辑以通过将 LocalPrintServer.DefaultPrintQueue 传递给 PrintDialog 进行无人值守打印,则此代码有效。

我已经剖析了处理打印机名称的方式,但我似乎无法找出传递网络打印机的正确方式。

这是我当前的代码(我已经尝试了很多次迭代,结果都一样,我已经记不清了......哈哈)。

XAML- 我正在使用已安装的打印机列表填充 XAML 组合框,如下所示 -

    <Window x:Class="PrintDialogTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:Printing="clr-namespace:System.Printing;assembly=System.Printing"
        mc:Ignorable="d"
        Title="MainWindow" Height="550" Width="450">
    <Window.Resources>
        <Printing:LocalPrintServer x:Key="localPrintServer1"/>
        <ObjectDataProvider x:Key="printerCollection"
                        ObjectInstance="{StaticResource localPrintServer1}"
                        MethodName="GetPrintQueues">
            <ObjectDataProvider.MethodParameters>
                <x:ArrayExtension Type="{x:Type Printing:EnumeratedPrintQueueTypes}">
                    <Printing:EnumeratedPrintQueueTypes>Local</Printing:EnumeratedPrintQueueTypes>
                    <Printing:EnumeratedPrintQueueTypes>Connections</Printing:EnumeratedPrintQueueTypes>
                </x:ArrayExtension>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>.............
    <ComboBox x:Name="cboPrinters" HorizontalAlignment="Left" Height="34" Margin="53,414,0,0" VerticalAlignment="Top" Width="354" ItemsSource="{Binding Source={StaticResource printerCollection}}" DisplayMemberPath="Name" FontSize="14"/>

这很好用,并为我提供了所有已安装的打印机。

如果我运行应用程序并选择两台联网打印机以外的任何打印机,则下面的代码(来自MainWindow.xaml.cs 打印按钮的点击事件)可以工作 -

    // Create a PrintDialog  
            PrintDialog printDlg = new PrintDialog();
            // Create a PrintQueue and PrintServer - assign the user selected printer to the PrintQueue
            printDlg.PrintQueue = new PrintQueue(new PrintServer(), cboPrinters.Text);

如前所述,我尝试了多种方法来格式化传递给PrintQueue 的名称值,但均未成功。

虽然我认为这可能是修复,但它在使用时也会触发错误 -

PrintServerException - “…name is invalid” even though I can access the path from windows

希望我已经提供了足够的信息,但如果没有,请告诉我,我会添加任何其他需要的信息。

任何帮助将不胜感激,并感谢您提前回复。

更新 - 如果我使用网络打印服务器的名称对 PrintServer 的实例化进行硬编码,则该代码也适用于网络打印机(需要注意)-

printDlg.PrintQueue = new PrintQueue(new PrintServer(@"\\NetworkPrintServerNameHere"), (string)cboPrinters.SelectedValue);

但显然此代码在实际使用中并不实用,因为我们的打印机列表中可以有多个 PrintServer 名称。我需要找到一种方法来获取当前所选打印机的 PrintServer 名称。

【问题讨论】:

  • 请注意,您应该设置SelectedValuePath="Name" 并使用(string)cboPrinters.SelectedValue 而不是cboPrinters.Text
  • 感谢您的回复.....如上所述(您无法知道),我已经尝试了多种方法来解决错误,我最初拥有的代码和您一样已概述。结果是一样的。但我会回去再试一次确认。
  • 这就是使用 WPF ComboBox 的方式。并不是说它会解决你的问题。
  • 我删除了关于在 Windows 7 上调试时代码工作的评论,因为两台机器之间创建的打印机不同(我当前的开发盒是 Win 10,我也可以访问 Win 7 开发机)。我正在调查与分配了非本地打印服务器的打印队列有什么冲突。使用本地打印服务器的打印队列工作正常 - 分配给它们的网络打印服务器的打印队列失败。

标签: c# wpf xaml printing printdialog


【解决方案1】:

因此,使用为组合框创建记录集的请求顶部的代码,我们可以通过将其设置为跟随-

printDlg.PrintQueue = new PrintQueue(new PrintServer(((System.Printing.PrintQueue)cboPrinters.SelectedItem).HostingPrintServer.Name), (string)cboPrinters.SelectedValue);

我不再收到错误,并且可以打印到用户选择的任何本地和网络打印机。

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2011-01-21
    • 1970-01-01
    • 2015-07-07
    相关资源
    最近更新 更多