locked
Printing RTL DataGrid (dot net 4) with hebrew fonts results in mirrored output RRS feed

  • Question

  • Hi,

    I've seen this issue at older posts, and no solution yet.

    I have a RTL DataGrid with hebrew text (same problem would be in any other RTL lang.)

    When I try to print it:

    PrintDialog dlg = new PrintDialog();
          if (dlg.ShowDialog() == true)
          { dlg.PrintVisual(grdRegistration, "Report"); }
    
    

    I get it printed out Mirrored (I can read it only if I look at it in the mirror)

    On the screen I see everything fine of-course.

    Any ideas why it happens, and how to fix it ?

    related questions I've found on this topic:

    http://connect.microsoft.com/VisualStudio/feedback/details/320720/text-with-flowdirection-righttoleft-is-mirrored-when-printing-using-printdialog-printvisual-in-wpf

    http://social.msdn.microsoft.com/Forums/en/wpf/thread/3064e0c3-59ab-44fb-80fa-308df574d31f

     

     

     


    Dani Kaplan
    Sunday, April 3, 2011 8:12 AM

Answers

  • Hi Kdani,

    As explained in the connect post you linked, this problem is caused by the implicit mirroring transform.

    Here is the workaround attached in that connect post:

        private static void PrintDialodPrintVisualWithRTLWorkaround(PrintDialog printDialog, FrameworkElement fe, string description)
        {
          FlowDirection parentFd = fe.FlowDirection;
          object temp = fe.ReadLocalValue(FrameworkElement.FlowDirectionProperty);
          FlowDirection localFd = (temp != DependencyProperty.UnsetValue) ? ((FlowDirection)temp) : FlowDirection.LeftToRight;
          object oldRenderTransform = fe.ReadLocalValue(UIElement.RenderTransformProperty);
    
          if (localFd != parentFd)
          {
            //apply implicit mirroring transform workaround
            fe.RenderTransform = new MatrixTransform(-1.0, 0.0, 0.0, 1.0, fe.RenderSize.Width, 0.0);
    
            // Wait for the render transform to take effect
            // Unfortunately this also means that the end user will see a temporaty mirroring effect
            DispatchPendingOperations();
          }
    
          printDialog.PrintVisual(fe, description);
    
          if (localFd != parentFd)
          {
            // undo workaround
            fe.SetValue(UIElement.RenderTransformProperty, oldRenderTransform);
          }
        }
    
        private static void DispatchPendingOperations()
        {
          DispatcherFrame frame = new DispatcherFrame(true);
          Dispatcher.CurrentDispatcher.BeginInvoke(
            DispatcherPriority.SystemIdle, 
            (DispatcherOperationCallback)ExitDispatcherFrame,
            frame);
          Dispatcher.PushFrame(frame);
        }
    
        private static object ExitDispatcherFrame(object arg)
        {
          DispatcherFrame frame = (DispatcherFrame)arg;
          frame.Continue = false;
          return null;
        }
    

    The above workaruond might cause the UI to be mirrored for a short time. I suggest you to use the following workaround instead.

        <Grid FlowDirection="LeftToRight">
          <DataGrid FlowDirection="RightToLeft">
          </DataGrid>
        </Grid> 
    

    For any RTL visual that you want to print, please make sure its FlowDirection is RTL and its logical parent's FlowDirection is LTR. This can effictively provent the problem from happening.

    If you still have any questions or concerns about this issue, please feel free to let me know.


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Min Zhu Tuesday, April 12, 2011 3:46 AM
    • Unmarked as answer by Min Zhu Wednesday, April 13, 2011 3:27 AM
    • Marked as answer by Min Zhu Friday, April 29, 2011 1:59 AM
    Monday, April 4, 2011 5:30 AM

All replies

  • Hi Kdani,

    As explained in the connect post you linked, this problem is caused by the implicit mirroring transform.

    Here is the workaround attached in that connect post:

        private static void PrintDialodPrintVisualWithRTLWorkaround(PrintDialog printDialog, FrameworkElement fe, string description)
        {
          FlowDirection parentFd = fe.FlowDirection;
          object temp = fe.ReadLocalValue(FrameworkElement.FlowDirectionProperty);
          FlowDirection localFd = (temp != DependencyProperty.UnsetValue) ? ((FlowDirection)temp) : FlowDirection.LeftToRight;
          object oldRenderTransform = fe.ReadLocalValue(UIElement.RenderTransformProperty);
    
          if (localFd != parentFd)
          {
            //apply implicit mirroring transform workaround
            fe.RenderTransform = new MatrixTransform(-1.0, 0.0, 0.0, 1.0, fe.RenderSize.Width, 0.0);
    
            // Wait for the render transform to take effect
            // Unfortunately this also means that the end user will see a temporaty mirroring effect
            DispatchPendingOperations();
          }
    
          printDialog.PrintVisual(fe, description);
    
          if (localFd != parentFd)
          {
            // undo workaround
            fe.SetValue(UIElement.RenderTransformProperty, oldRenderTransform);
          }
        }
    
        private static void DispatchPendingOperations()
        {
          DispatcherFrame frame = new DispatcherFrame(true);
          Dispatcher.CurrentDispatcher.BeginInvoke(
            DispatcherPriority.SystemIdle, 
            (DispatcherOperationCallback)ExitDispatcherFrame,
            frame);
          Dispatcher.PushFrame(frame);
        }
    
        private static object ExitDispatcherFrame(object arg)
        {
          DispatcherFrame frame = (DispatcherFrame)arg;
          frame.Continue = false;
          return null;
        }
    

    The above workaruond might cause the UI to be mirrored for a short time. I suggest you to use the following workaround instead.

        <Grid FlowDirection="LeftToRight">
          <DataGrid FlowDirection="RightToLeft">
          </DataGrid>
        </Grid> 
    

    For any RTL visual that you want to print, please make sure its FlowDirection is RTL and its logical parent's FlowDirection is LTR. This can effictively provent the problem from happening.

    If you still have any questions or concerns about this issue, please feel free to let me know.


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Min Zhu Tuesday, April 12, 2011 3:46 AM
    • Unmarked as answer by Min Zhu Wednesday, April 13, 2011 3:27 AM
    • Marked as answer by Min Zhu Friday, April 29, 2011 1:59 AM
    Monday, April 4, 2011 5:30 AM
  • Hi Kdani,

    Just checking in to see if the information was helpful. Please let us know if you would like further assistance.

    Have a great day!


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, April 6, 2011 2:01 AM
  • Hi,

    I've tried the little workaround -

    <Grid FlowDirection="LeftToRight">
       <DataGrid FlowDirection="RightToLeft">
       </DataGrid>
      </Grid> 

    But it didnt' do the trick, still comes out mirrored.

    maybe it's b/c the grid is a user control that sits on a tab.

    I will try the "long" workaround, and see if it helps today.

    Thanks for the help and thoughts :-)

    Dani.

     

     


    Dani Kaplan
    Wednesday, April 6, 2011 5:32 AM
  • Hi Kdani,

    Thanks for the update.

    Have you tried adding an additional grid around the DataGrid for the second workaround? Based on my understanding, the problem won't happen in the first place if the visual being printed is RTF and its parent is LTR.


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, April 6, 2011 6:01 AM
  • Hi Kdani,

    Have you resolved the problem?


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, April 8, 2011 2:35 AM
  • Hi Kdani,

    I am marking this issue as "Answered". If you have any new questions or concerns about this issue, please feel free to let me know.

    Thank you and have a nice day!


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, April 12, 2011 3:46 AM
  • Hi Min Zhu,

    I'm currently outside IL, so I wasn't able to complete the check, I will do it when I return - and then I hope it will approve your reply, as the little workaroud doesn't work, but I haven't tried yet the long one.

    Thanks for keeping track on this issue, and I promise to update asap.

    Dani

     

     


    Dani Kaplan
    Tuesday, April 12, 2011 11:14 AM
  • Hi Kdani,

    Thanks for the update.

    I have tried both workarounds and they seem to work for me. For the short workaround, please make sure the wrapper grid is added to the visual you pass to the PrintVisual method, i.e. grdRegistration in your code. For example,

    <Grid FlowDirection="LeftToRight">
      <Grid Name="grdRegistration" FlowDirection="RightToLeft">
      </Grid >
     </Grid> 
    

    If this still doesn't work, please feel free to let me know.

    Best regards,


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, April 13, 2011 1:53 AM
  • Hi Kdani,

    I am marking this issue as "Answered". If you have any new questions or concerns about this issue, please feel free to let me know.

    Thank you and have a nice day!

    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, April 29, 2011 1:59 AM
  • Your workaround worked, I just made the child RightToLeft and the Parent LeftToRight and everything worked greate

    "Always there's a room"

    Saturday, September 22, 2012 6:48 AM
  • Thanks it works for me, and it will be more helpful if you set the FlowDirection using the code as below

     public static void PrintWithRtlWorkaround(FrameworkElement ui)
            {
                var  printDialog = new PrintDialog();
    
                var parent = ui.GetVisualParent();
                ui.FlowDirection = FlowDirection.RightToLeft;
                parent.FlowDirection = FlowDirection.LeftToRight;
    
                PrintDialodPrintVisualWithRtlWorkaround(printDialog, ui, "RTL Testing");
            }

    Wednesday, February 20, 2019 10:06 PM