WPF打印控件内容

当我们想打印控件内容时,如一个Grid中的内容,可以用WPF中PrintDialog类的PrintVisual()方法来实现

界面如下:

XAML代码如下

XML 复制代码
<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="300"/>
        </Grid.ColumnDefinitions>
        <Grid Grid.Column="0">

            <Grid Width="800" Name="grid1">
                <TextBlock TextWrapping="Wrap" FontSize="15">
                Control authors who want to customize the arrange pass of layout processing should override this method. The implementation pattern should call M:System.Windows.UIElement.Arrange(System.Windows.Rect) on each visible child element, and pass the final desired size for each child element as the finalRect parameter. Parent elements should call M:System.Windows.UIElement.Arrange(System.Windows.Rect) on each child, otherwise the child elements will not be rendered.
Many derived classes offer implementations of this method. Prominent ones include: M:System.Windows.Window.ArrangeOverride(System.Windows.Size), M:System.Windows.Controls.Page.ArrangeOverride(System.Windows.Size) and M:System.Windows.Controls.Control.ArrangeOverride(System.Windows.Size).
                </TextBlock>
            </Grid>
        </Grid>

        <Grid Grid.Column="1">
            <Button Height="30" VerticalAlignment="Top" Click="Button_Click">打印</Button>
        </Grid>
    </Grid>

当我们点击按钮时,进行打印

按钮事件:

复制代码
           PrintDialog pd = new PrintDialog();
            if (pd.ShowDialog() == true)
            {
                pd.PrintVisual(this.grid1, "");
            }

这时我们会发现,虽然 打印的内容是指定的,但打印的大小却是整个窗体的大小,而不仅仅是指定的区域大小。

然后我们就需要用到UIElement的Arrange 方法

MSDN上的解释是

定位子元素,并确定 UIElement 的大小。 父元素从它们的 ArrangeCore 实现(或者是 WPF 框架级别等效项)调用此方法,以便形成递归布局更新。此方法产生第二次布局更新。

修改后的代码如下:

复制代码
1 if (pd.ShowDialog() == true)
2             {                
3                 this.grid1.Arrange(new Rect(new Size(grid1.ActualWidth, grid1.ActualHeight)));
4                 pd.PrintVisual(this.grid1, "");               
5             }

这样操作以后,打印的大小不再是整 个窗体的大小了,但打印完之后 ,控件 的位置却发生了变化 ,这时候我们只需要再调用一次Arrange方法,将它放回原来的位置就行了

cs 复制代码
 if (pd.ShowDialog() == true)
             {               
                 Window window = Window.GetWindow(grid1);
                 Point point = grid1.TransformToAncestor(window).Transform(new Point(0, 0));//获取当前控件 的坐标
                 this.grid1.Measure(new Size(grid1.ActualWidth,grid1.ActualHeight));
                 this.grid1.Arrange(new Rect(new Size(grid1.ActualWidth, grid1.ActualHeight)));
                 pd.PrintVisual(this.grid1, "");
                 this.grid1.Arrange(new Rect(point.X, point.Y, grid1.ActualWidth, grid1.ActualHeight));//设置为原来的位置
             }

这样就可以打印控件 内容了。

如果 想对打印机进行设置,可以查找 WPF PrintDialog的使用方法,下面是简单的设置

cs 复制代码
                 PrintTicket pt = new PrintTicket();
                 PageMediaSize p = new PageMediaSize(PageMediaSizeName.ISOA4);
                 //pt.PageBorderless = PageBorderless.Unknown;
                 pt.PageMediaSize = p;
                 //pt.PageOrientation = PageOrientation.Portrait;
                 pd.PrintTicket = pt;
相关推荐
TA远方1 小时前
【WPF】桌面程序使用谷歌浏览器内核CefSharp控件详解
wpf·浏览器·chromium·控件·cefsharp·cefsharp.wpf
Macbethad12 小时前
工业设备数据采集主站程序技术方案
wpf
关关长语21 小时前
HandyControl 3.5.x 版本 ListViewItem不显示问题
windows·wpf
Macbethad21 小时前
工业设备维护程序技术方案
wpf
Macbethad21 小时前
工业设备配方管理系统技术方案
wpf
喵叔哟1 天前
7.日志系统深入
wpf
清风徐来Groot1 天前
WPF布局之Grid
wpf
清风徐来Groot1 天前
WPF布局之WrapPanel
wpf
Macbethad1 天前
WPF工业设备工艺配方流程程序技术方案
wpf
清风徐来Groot1 天前
WPF布局之UniformGrid
wpf