2017-04-24 80 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; 
    }