2017-04-24 57 views
0

以我WPF应用程序我动态加载XAML在运行时从XML绘图。该图是一个复杂的一系列嵌套的画布和几何形状的“路径的(例如):VisualTreeHelper.GetDescendantBounds返回“空”(无限远)

<?xml version="1.0" encoding="utf-8"?> 
<Canvas Width="1593" Height="1515"> 
    <Canvas.Resources /> 
    <Canvas> 
     <Path Fill="…" Data="…"/> 
     <Path Fill="…" Data="…"/> 
     <Path Fill="…" Data="…"/> 
     <Canvas> 
      <Canvas> 
       <Path Stroke="…" StrokeThickness="…" StrokeMiterLimit="…" StrokeLineJoin="…" StrokeEndLineCap="…" Data="…"/> 
       <Path Stroke="…" StrokeThickness="…" StrokeMiterLimit="…" StrokeLineJoin="…" StrokeEndLineCap="…" Data="…"/> 
      </Canvas> 
     </Canvas> 
     <Path Fill="…" Data="…"/> 
     <Path Fill="…" Data="…"/> 
     <Path Fill="…" Data="…"/> 
    </Canvas> 
</Canvas> 

外帆布”高度/宽度被错误地设定,因为许多路径表达式的超过这些尺寸。我无法控制这个源XML,所以我需要在绘图加载后在运行时修复它。要加载图纸我用类似的代码如下:

public static Canvas LoadDrawing(string xaml) 
{ 
    Canvas drawing = null; 
    using (var stringreader = new StringReader(xaml)) 
    { 
     using (var xmlReader = new XmlTextReader(stringreader)) 
     { 
      drawing = (Canvas)XamlReader.Load(xmlReader); 
     } 
    } 
    return drawing; 
} 

然后,我尝试重置画布大小,使用下面的代码:

var canvas = LoadDrawing(…); 
    someContentControOnTheExistingPage.Content = canvas; 
    var bounds = VisualTreeHelper.GetDescendantBounds(canvas); // << 'bounds' is empty here. 
    canvas.Width = bounds.Width; 
    canvas.Height = bounds.Height; 

除此之外,在点,我创建画布元素,边界是空的。但是,如果我只是连线一个简单的按钮并在同一个画布上交互调用GetDescendantBounds(),那么我会收到预期的高度/宽度。

我的外卖是GetDescendantBounds()不工作,除非有新的控制布局已经完成。所以我的问题是:

  1. 有没有一种方法,我可以在运行之前GetDescendantBounds强制布局计算()?或者...
  2. 有另一种方式,我可以得到一个可视化树的范围/程度,事先将它添加到它的父?

感谢

-John

回答

0

有没有一种方法,我可以在运行之前GetDescendantBounds强制布局计算?

是,调用CanvasArrangeMeasure方法:

var canvas = LoadDrawing("..."); 
someContentControOnTheExistingPage.Content = canvas; 
canvas.Arrange(new Rect(someContentControOnTheExistingPage.RenderSize)); 
canvas.Measure(someContentControOnTheExistingPage.RenderSize); 
var bounds = VisualTreeHelper.GetDescendantBounds(canvas); 
canvas.Width = bounds.Width; 
canvas.Height = bounds.Height; 
+0

看起来奏效,感谢您的帮助! – JohnKoz

+0

不客气,但请记住,upvote有用的答案:https://stackoverflow.com/help/privileges/vote-up – mm8

0

首先,你需要在你的XAML字符串添加这一行。

xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' 

这是找到控件和属性的C#代码示例。

public void LoadXaml() 
    { 
     string canvasString = @"<Canvas Name='canvas1' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' Width = '1593' Height = '1515'> </Canvas>"; 
     var canvas = LoadDrawing(canvasString); 

     //Use this line you will find height and width. 
     Canvas canvasCtrl = (Canvas)LogicalTreeHelper.FindLogicalNode(canvas, "canvas1"); 

     // var bounds = VisualTreeHelper.GetDescendantBounds(canvas); // << 'bounds' is empty here. 

     canvas.Width = canvasCtrl.Width; //bounds.Width; 
     canvas.Height = canvasCtrl.Height; //bounds.Height; 
    }