WPF валидация красной границы не отображается во время печати - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь напечатать Window, содержащий один TextBox. Когда отображается на экране, красная граница ошибки проверки правильности присутствует. При печати через PrintDialog граница отсутствует. Окно определяется как:

public partial class ReportPage : INotifyDataErrorInfo
{
    public ReportPage()
    {
        DataContext = this;
        SomeText = "hi there";
        InitializeComponent();
    }

    public string SomeText { get; set; }

    public IEnumerable GetErrors(string propertyName)
    {
        return propertyName == "SomeText" ? new [] {"some error"} : null;
    }

    public bool HasErrors => true;

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
}

Обратите внимание, что он служит Window, моделью представления и реализацией ошибок. Он указывает, что свойство lone, SomeText, содержит ошибку. Соответствующий XAML выглядит следующим образом:

<Window x:Class="ReportPage"
        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"
        mc:Ignorable="d">
    <Grid x:Name="MainContent" VerticalAlignment="Center" HorizontalAlignment="Center">
        <TextBox x:Name="MyText" Text="{Binding SomeText}"/>
    </Grid>
</Window>  

Для печати содержимого Window я использую:

var printDialog = new PrintDialog { PrintTicket = { PageOrientation = PageOrientation.Portrait } };
printDialog.ShowDialog();

var caps = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
var rect = new Rect(new Point(caps.PageImageableArea.OriginWidth, caps.PageImageableArea.OriginHeight),
    new Size(caps.PageImageableArea.ExtentWidth, caps.PageImageableArea.ExtentHeight));

var pageSize = rect.Size;
var origin = rect.TopLeft;
var fullSize = new Size(printDialog.PrintTicket.PageMediaSize.Width.Value,
    printDialog.PrintTicket.PageMediaSize.Height.Value);

var page = new ReportPage
{
    Margin = new Thickness(
        Math.Max(72 - origin.X, 0),
        Math.Max(48 - origin.Y, 0),
        Math.Max(72 - (fullSize.Width - pageSize.Width - origin.X), 0),
        Math.Max(96 - (fullSize.Height - pageSize.Height - origin.Y), 0))
};

page.MainContent.Measure(pageSize);
page.MainContent.Arrange(new Rect(origin, pageSize));
page.MainContent.UpdateLayout();

printDialog.PrintVisual(page.MainContent, "some description");

Я вижу TextBox просто отлично, но красной границы нет. Я пытался добавить <AdornerDecorator> вокруг MainContent Grid безрезультатно. Что происходит при отображении на экране Window, чтобы сделать видимой красную рамку, чего нет при печати?

1 Ответ

0 голосов
/ 11 января 2019

Во-первых, украшения не отображаются без отображения Window. Чтобы это исправить, Window перед печатью отображается за кадром (Left / Top произвольно установлены на -10000 и ShowInTaskbar / ShowActivated установлены на false):

page.Show();
page.MainContent.Measure(pageSize);
page.MainContent.Arrange(new Rect(origin, pageSize));
page.MainContent.UpdateLayout();

printDialog.PrintVisual(page.MainContent, "some description");

Во-вторых, при печати только MainContent отсутствует слой украшений, поэтому его необходимо добавить (см. XPS-печать Adorner :

<Window x:Class="ReportPage"
        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"
        mc:Ignorable="d"
    ShowInTaskbar="False"
    Left="-10000"
    Top="-10000"
    ShowActivated="False">
    <Window.Resources>
        <Style TargetType="{x:Type ContentControl}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ContentControl}">
                        <AdornerDecorator>
                            <ContentPresenter
                                Content="{TemplateBinding Content}"
                                ContentTemplate="{TemplateBinding ContentTemplate}" />
                        </AdornerDecorator>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>    
    <ContentControl x:Name="MainContent" VerticalAlignment="Center" HorizontalAlignment="Center">
        <TextBox x:Name="MyText" Text="{Binding SomeText}"/>
    </Grid>
</Window>  
...