所以我构建了一个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
答案 0 :(得分:0)
我发现可能Parent
属性为NULL,但组件明显附加到某些Visual。在这种情况下,您需要使用var parentObject = VisualTreeHelper.GetParent(child);
,这将可靠地告诉您可视父级。您只需使用以下代码段:
var parentObject = VisualTreeHelper.GetParent(child);
if (parentObject != null)
{
parentObject.Children.Remove(child);
}