В файле My Print PDF не отображаются данные оригинального окна, связанные в виде - C# MVVM - PullRequest
1 голос
/ 15 апреля 2020

Я пытаюсь распечатать свое окно (предварительный просмотр) с использованием архитектуры MVVM. До сих пор я смог получить контроль над окном в печать. Но это не показывает привязки данных.

Это мой код PrintPreview.xaml

<ScrollViewer VerticalScrollBarVisibility="Auto">
    <!--Main Grid-->
    <Grid x:Name="MainGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2.5*"/>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="2.5*"/>
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height ="1.5*"/>
            <RowDefinition Height ="1.7*"/>
            <RowDefinition Height ="5*" MinHeight="200"/>
            <RowDefinition Height ="7*" MinHeight="200"/>
            <RowDefinition Height ="6*" MinHeight="100"/>
            <RowDefinition Height ="2*"/>
        </Grid.RowDefinitions>

        <Grid Grid.RowSpan="2" Grid.ColumnSpan="3" Background="#9dc6a7"/>

        <!--Patient Id block-->
        <StackPanel Grid.ColumnSpan="2" Style="{StaticResource StackpanelStyle}">
            <Label FontSize="16" FontWeight="Bold" Foreground="White">
                Patient ID :
            </Label>
            <Label FontSize="16" Foreground="White" Margin="5,0,0,0" Content="{Binding Path=PatientID}"/> 
        </StackPanel>

        <!--Date block-->
        <StackPanel Grid.ColumnSpan="3" Style="{StaticResource StackpanelStyle}" HorizontalAlignment="Right">
            <Label FontSize="16" FontWeight="Bold" Foreground="White">
                Date :
            </Label>
            <Label Name="date_time" FontSize="16" Foreground="White" Margin="5,0" Content="{Binding Path=CurrentDate}"/>
        </StackPanel>

        <!--Title block-->
        <TextBlock Grid.Row="1" Grid.ColumnSpan="3"  HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" FontWeight="Bold" TextDecorations="Underline" Foreground="White">
            Patient Registration Information
        </TextBlock>

        <!--Sub grid 1-->
        <Grid Grid.Row="2" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Stretch" Margin="25,10,25,10">

            <!--User's image View and name-->
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Vertical">
                <Ellipse Width="150" Height="150">
                    <Ellipse.Fill>
                        <ImageBrush x:Name="ImageViewer2" ImageSource="{Binding Path=PatientImageSource}"/>
                    </Ellipse.Fill>
                </Ellipse>
                <StackPanel HorizontalAlignment="Left" Orientation="Horizontal" Margin="0,10">
                    <Label Style="{StaticResource LabelStyles}" Margin="0">Patient Name :</Label>
                    <TextBlock x:Name="ViewName" Style="{StaticResource TextBlockStyle}" Text="{Binding Path = PatientName}"/>
                </StackPanel>
            </StackPanel>
        </Grid>

        <!--Sub grid 2-->
        <GroupBox Grid.Row="3" Grid.ColumnSpan="3" HorizontalAlignment="Stretch"  VerticalAlignment="Center" Margin="25,-35,25,0">
            <GroupBox.Header>
                <TextBlock Style="{StaticResource TextBlockStyleControl}">Patient Personal Information</TextBlock>
            </GroupBox.Header>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="500*"/>
                    <ColumnDefinition Width="500*"/>
                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>
                    <RowDefinition Height="5*"/>
                    <RowDefinition Height="3*" MaxHeight="80"/>
                </Grid.RowDefinitions>

                <StackPanel Grid.Row="0" Grid.Column="0" Orientation="Vertical" Margin="10,5">
                    <Label Style="{StaticResource PreviewLabelStyles}" >Address :</Label>
                    <TextBlock x:Name="ViewANum"  Style="{StaticResource TextBlockStyle}" Text="{Binding Path =  PatientAddress.Number}"/>
                    <TextBlock x:Name="ViewAStrt" Style="{StaticResource TextBlockStyle}" Text="{Binding Path =  PatientAddress.Street}"/>
                    <TextBlock x:Name="ViewACity" Style="{StaticResource TextBlockStyle}" Text="{Binding Path =  PatientAddress.City}"/>
                </StackPanel>

                <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Vertical" Margin="50,5,10,10">
                    <Label  Style="{StaticResource PreviewLabelStyles}">Gender :</Label>
                    <TextBlock x:Name="ViewGender" Style="{StaticResource TextBlockStyle}" Text="{Binding Path = PatientGender}"/>
                </StackPanel>

                <StackPanel Grid.Row="1" Grid.Column="0" Orientation="Vertical" Margin="10,5">
                    <Label  Style="{StaticResource PreviewLabelStyles}">Date of Birth :</Label>
                    <TextBlock x:Name="ViewDob" Style="{StaticResource TextBlockStyle}" Text="{Binding Path = PatientDateOfBirth}"/>
                </StackPanel>

                <StackPanel Grid.Row="1" Grid.Column="1" Orientation="Vertical" Margin="50,5,10,5">
                    <Label Style="{StaticResource PreviewLabelStyles}">Age :</Label>
                    <TextBlock x:Name="ViewAge" Style="{StaticResource TextBlockStyle}" Text="{Binding Path = PatientAge}"/>
                </StackPanel>
            </Grid>
        </GroupBox>

        <!--Sub grid 3-->
        <GroupBox Grid.Row="4" Grid.ColumnSpan="3" HorizontalAlignment="Stretch"  VerticalAlignment="Center" Margin="25,-25,25,0">
            <GroupBox.Header>
                <TextBlock Style="{StaticResource TextBlockStyleControl}">Patient Medical Information</TextBlock>
            </GroupBox.Header>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="500*"/>
                    <ColumnDefinition Width="500*"/>
                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>
                    <RowDefinition Height="3*"/>
                    <RowDefinition Height="3*" />
                </Grid.RowDefinitions>

                <StackPanel Grid.Row="0" Grid.Column="0" Orientation="Vertical" Margin="10,5">
                    <Label Style="{StaticResource PreviewLabelStyles}">Department :</Label>
                    <TextBlock x:Name="ViewDepartment" Style="{StaticResource TextBlockStyle}" Text="{Binding Path=PatientDepartment}"/>
                </StackPanel>

                <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Vertical" Margin="50,5,10,0">
                    <Label  Style="{StaticResource PreviewLabelStyles}">Ward :</Label>
                    <TextBlock x:Name="ViewWard" Style="{StaticResource TextBlockStyle}" Text="{Binding Path=PatientWard}"/>
                </StackPanel>

                <StackPanel Grid.Row="1" Grid.Column="0" Orientation="Vertical" Margin="10,5,10,10">
                    <Label  Style="{StaticResource PreviewLabelStyles}">Doctor in Charge :</Label>
                    <TextBlock x:Name="ViewDoc" Style="{StaticResource TextBlockStyle}" Text="{Binding Path=PatientDotorcInCharge}"/>
                </StackPanel>
            </Grid>
        </GroupBox>

        <Button Grid.Row="5" Grid.Column="2" Style="{StaticResource ButtonStyle}" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="20,7,26,0" Content="Print Content" Command="{Binding Path=PrintCommand}"/>

    </Grid>
</ScrollViewer>

Это мой код ViewPodeview PrintPreview,

class PrintPreviewViewModel
{
    #region Data Members
    private IWindowService m_windowService;
    #endregion

    #region Constructors
    public PrintPreviewViewModel(PatientRecordDetailsModel patient)
    {
        string id = patient.PatientId;

        PatientID = id.PadRight(6).Substring(0, 6);
        PatientName = patient.PatientName;
        PatientAddress = patient.PatientAddress;
        PatientGender = patient.PatientGender;
        PatientDateOfBirth = patient.PatientDateOfBirth.ToShortDateString();
        PatientAge = patient.PatientAge;
        PatientImageSource = patient.PatientImageSource;
        PatientDepartment = patient.PatientDepartment;
        PatientWard = patient.PatientWard;
        PatientDotorcInCharge = patient.PatientDoctorInCharge;

        m_windowService = new WindowService();
    }
    #endregion

    #region Properties
    public string PatientID { get; set; }

    public string PatientName { get; set; }

    public PatientAddress PatientAddress { get; set; }

    public string PatientGender { get; set; }

    public string PatientDateOfBirth { get; set; }

    public int PatientAge { get; set; }

    public ImageSource PatientImageSource { get; set; }

    public string PatientDepartment { get; set; }

    public string PatientWard { get; set; }

    public string PatientDotorcInCharge { get; set; }
    #endregion

    #region <PrintPreview> Members
    public string CurrentDate => m_windowService.GetCurrentDate();
    #endregion

    #region Properties : Commands
    public ICommand PrintCommand
    {
        get => new PatientRecordDetailsCommands(param => OnPrintCommandExecute(), param => OnPrintCommandCanExecute());
    }
    #endregion

    #region Handlers : Commands
    private void OnPrintCommandExecute()
    {
        m_windowService.PrintWindow();
    }

    private bool OnPrintCommandCanExecute()
    {
        return true;
    }
    #endregion

}
}

Как вы видите, я открываю окно printPreview из другого окна. окно через класс обслуживания. Объект пациента отправляется через это. Также реализация команды кнопки печати также определена в том же классе обслуживания. Я использовал этот подход для уменьшения нарушений MVVM. Это мой класс обслуживания

   class WindowService : IWindowService
   {

    public void CreateWindow(PatientRecordDetailsModel patient)
    {
        PrintPreview printPreview = new PrintPreview();
        printPreview.DataContext = new PrintPreviewViewModel(patient);
        printPreview.Show();
    }

    public string GetCurrentDate()
    {
        DateTime dateTime = DateTime.Now;

        string date = dateTime.ToString("d");
        string time = dateTime.ToString("T");
        string Date_Time = date + " " + time;

        return Date_Time;
    }

    public void PrintWindow()
    {
        PrintPreview printPreview = new PrintPreview();
        PrintDialog printDlg = new PrintDialog();            
        PrintQueue ReceiptPrinter = new LocalPrintServer().GetPrintQueue("Microsoft Print To PDF");
        PrintCapabilities PC = ReceiptPrinter.GetPrintCapabilities();
        printDlg.PrintQueue = ReceiptPrinter;
        printPreview.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
        Size PreGridSize = printPreview.DesiredSize;
        double Scale = Math.Min(PC.PageImageableArea.ExtentWidth / PreGridSize.Width, PC.PageImageableArea.ExtentHeight / PreGridSize.Height);
        printPreview.LayoutTransform = new System.Windows.Media.ScaleTransform(Scale, Scale);
        Size PaperSize = new Size(PC.PageImageableArea.ExtentWidth, Math.Min(PC.PageImageableArea.ExtentHeight, PreGridSize.Height));
        printPreview.Measure(PaperSize);
        Point ptGrid = new Point(PC.PageImageableArea.OriginWidth, PC.PageImageableArea.OriginHeight);
        printPreview.Arrange(new Rect(ptGrid, PaperSize));

        Application.Current.Dispatcher.BeginInvoke(
            new Action(delegate () { printDlg.PrintVisual(printPreview.MainGrid, "PrintPreview"); }),
            DispatcherPriority.Send);

    }
}

Я попытался назначить объект пациента тексту данных внутри PrintWindow (), но он возвращает нулевой объект.

Это оригинальное окно printPreview

Вот так выглядит печать

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

1 Ответ

0 голосов
/ 15 апреля 2020

Ваша проблема в том, что вы не назначаете DataContext внутри вашей функции PrintWindow.

давайте посмотрим

    public void PrintWindow()
    {

здесь мы создаем новое представление для печати

        PrintPreview printPreview = new PrintPreview();
        PrintDialog printDlg = new PrintDialog();            
        PrintQueue ReceiptPrinter = new LocalPrintServer().GetPrintQueue("Microsoft Print To PDF");
        PrintCapabilities PC = ReceiptPrinter.GetPrintCapabilities();
        printDlg.PrintQueue = ReceiptPrinter;
        printPreview.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
        Size PreGridSize = printPreview.DesiredSize;
        double Scale = Math.Min(PC.PageImageableArea.ExtentWidth / PreGridSize.Width, PC.PageImageableArea.ExtentHeight / PreGridSize.Height);
        printPreview.LayoutTransform = new System.Windows.Media.ScaleTransform(Scale, Scale);
        Size PaperSize = new Size(PC.PageImageableArea.ExtentWidth, Math.Min(PC.PageImageableArea.ExtentHeight, PreGridSize.Height));
        printPreview.Measure(PaperSize);
        Point ptGrid = new Point(PC.PageImageableArea.OriginWidth, PC.PageImageableArea.OriginHeight);
        printPreview.Arrange(new Rect(ptGrid, PaperSize));

        Application.Current.Dispatcher.BeginInvoke(
            new Action(delegate () { printDlg.PrintVisual(printPreview.MainGrid, "PrintPreview"); }),
            DispatcherPriority.Send);

    }

как видите, вы не присваиваете ему текст данных. Действительно, функция createiwndow, в которой вы назначаете контекст данных, вообще не вызывается.

Здесь вы можете увидеть, что команда печати вызывает функцию PrintWindow вместо createwindow.

    #region Properties : Commands
    public ICommand PrintCommand
    {
        get => new PatientRecordDetailsCommands(param => OnPrintCommandExecute(), param => OnPrintCommandCanExecute());
    }
    #endregion

    #region Handlers : Commands
    private void OnPrintCommandExecute()
    {
        m_windowService.PrintWindow();
    }

    private bool OnPrintCommandCanExecute()
    {
        return true;
    }
    #endregion
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...