打印UI:指定的Visual已经是另一个Visual的子项或CompositionTarget的根

时间:2015-01-14 16:04:45

标签: c# wpf printing visual-studio-2013

所以我构建了一个WYSIWYG编辑器,允许用户在画布上拖放控件。然后,在按照他们喜欢的方式安排后,他们可以打印模板。

我遇到了Visual Tree的一些问题。

XAML

  <Grid>
    <Grid.ColumnDefinitions>
            <ColumnDefinition Width=".2*"/>
            <ColumnDefinition Width=".8*"/>
    </Grid.ColumnDefinitions>
    <StackPanel AllowDrop="False" Background="Gray">
      <!--REMOVED-->
    </StackPanel>
    <Canvas Grid.Column="1" AllowDrop="True" Width="600" Height="800"                 
            Background="White" x:Name="CanvasControl" 
            DataContext="{Binding CanvasVM}" 
            DragEnter="CanvasFlowDocument_DragEnter" 
            DragLeave="CanvasFlowDocument_DragLeave" 
            DragOver="CanvasFlowDocument_DragOver" 
            Drop="CanvasFlowDocument_Drop"/>
  </Grid>

C#

private void PrintCanvas()
{
   //Prompt for print
   PrintDialog pd = new PrintDialog();
   if (pd.ShowDialog()==true)
   {
       //Trying to use flow document for printing because I need to be able to control 
       //how the margins look on the page
       FlowDocument CanvasFlowDocument = new FlowDocument();
       BlockUIContainer buiCont = new BlockUIContainer();   

       //Get the parent of the CanvasControl because I can't pass the CanvasControl to my
       //Printer until it doesn't have a logical visual parent             
       Grid par = (Grid)CanvasControl.Parent;
       par.Children.Remove(CanvasControl);

       //Add Control to Block UI Container for printing
       buiCont.Child = CanvasControl;
       CanvasFlowDocument.Blocks.Add(buiCont);

        //Print the doc
       pd.PrintDocument((CanvasFlowDocument as IDocumentPaginatorSource).DocumentPaginator, "Template");

       //Now, in an attempt to re-add my canvas to the grid so my user can continue to see/manipulate it. I first clear the blocks
       CanvasFlowDocument.Blocks.Clear();

       //I even go as far as setting the Block UI Container child to null
       buiCont.Child = null;
       CanvasControl.UpdateLayout();

       //This is where explosions ensue...
       //The CanvasControl.Parent is null at this point, yet I still get the error below
       par.Children.Add(CanvasControl);
  }          
}

ERROR:

  

指定的Visual已经是另一个Visual或其根目录的子级   CompositionTarget

1 个答案:

答案 0 :(得分:0)

我发现可能Parent属性为NULL,但组件明显附加到某些Visual。在这种情况下,您需要使用var parentObject = VisualTreeHelper.GetParent(child);,这将可靠地告诉您可视父级。您只需使用以下代码段:

var parentObject = VisualTreeHelper.GetParent(child);
if (parentObject != null)
{
    parentObject.Children.Remove(child);
}