2011-12-28 57 views
1

我需要將多個用戶控件添加到畫布。 UserControl的大小取決於UserControlItemsControl中的項目數量。要正確定位控件並在用戶控件之間繪製互連線,我需要父畫布的絕對寬度/高度w.r.t。如何獲得這些? ActualHeightActualWidth正在返回0.在畫布中獲取用戶控件的渲染大小

我之前詢問similar question,但無法得到正確的答案。

編輯:添加XAML OD用戶控件

<UserControl x:Class="SilverlightApplication2.MyControl" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" 
DataContext="{Binding RelativeSource={RelativeSource Self}}" Loaded="UserControl_Loaded"> 

<Grid x:Name="LayoutRoot" Background="White"> 
    <Border CornerRadius="3" BorderThickness="1" BorderBrush="LightGray"> 
     <Grid Name="grid1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" > 
      <Grid.RowDefinitions> 
       <RowDefinition Height="40*" /> 
       <RowDefinition Height="136*" /> 
      </Grid.RowDefinitions> 
      ... 
      <Grid Name="gridPC" Grid.Row="1"> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="55*" /> 
        <RowDefinition Height="*" /> 
        <RowDefinition Height="55*" /> 
        <RowDefinition Height="*" /> 
       </Grid.RowDefinitions>    
       .... 

       <ItemsControl x:Name="pitems" ItemsSource="{Binding RowsP}" Grid.Row="1"> 
        <ItemsControl.ItemTemplate> 
         <DataTemplate> 
          <StackPanel Width="250" Orientation="Horizontal"> 
           <TextBlock Text="{Binding X}" Width="100" /> 
           <TextBlock Text="{Binding Y}" Width="130" /> 
          </StackPanel> 
         </DataTemplate> 
        </ItemsControl.ItemTemplate> 
       </ItemsControl> 

       ...... 
      </Grid> 
     </Grid> 
    </Border> 
</Grid> 

+0

您是否認爲您可以顯示用戶控件xaml的一些簡化代碼? – 2011-12-28 20:33:23

+0

包含UserControl的XAML – devnull 2011-12-28 20:45:39

回答

1

它已經很長一段時間,但我在幾年前做過類似的事情。我現在不記得所有的細節,今晚我有更多時間的時候我會看這個。我想給你一個快速的想法,告訴你爲什麼你的尺寸爲0。

這主要是因爲WPF中的佈局系統發生在兩遍,度量和安排過程中。首先,容器控制器(就你的情況而言,Panel)在完成此通行證後詢問它們的尺寸,容器將使用它們在測量通過中計算的尺寸來安排孩子。

我會推薦閱讀這篇MSDN文章,專注於測量和安排兒童部分。 http://msdn.microsoft.com/en-us/library/ms745058.aspx

讓我知道如果這沒有幫助,我會花更多的時間來刷新我對所有細節的記憶。

根據你的編輯,你可能想看看這篇文章,描述如何創建與線連接的對象。 http://denisvuyka.wordpress.com/2007/10/21/wpf-diagramming-drawing-a-connection-line-between-two-elements-with-mouse/

我認爲這更直接針對您的確切場景。

2

你有幾個選擇,你可以做到這一點,迫使打電話Window.MeasureWindow.Arrange將使所有的值被計算,或者你可以在Window.Loaded事件中得到這些值。同樣的問題已經被討論on this question

如果你上漿內容:

window.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
window.Arrange(new Rect(0, 0, window.DesiredWidth, window.DesiredHeight)); 

如果您使用的是明確的窗口大小:

window.Measure(new Size(Width, Height)); 
window.Arrange(new Rect(0, 0, window.DesiredWidth, window.DesiredHeight)); 

public MyWindow() 
{ 
    Loaded += delegate 
    { 
     // access ActualWidth and ActualHeight here 
    }; 

} 
1

ActualWidth,只有控制後ActualHeight工作已被渲染。

要獲得所需的控件大小,您需要通過調用它的方法來測量它自己。之後,您可以使用DesiredSize屬性,該屬性將包含您要查找的值。

還有由Charles Petzold的好文章處理類似的情況:

Thinking Outside the Grid

1

我積極創建一個Silverlight時間軸控制,我不要做一個措施,因爲以前的海報建議。我只是等待最終的onsize調用或其他依賴屬性OnChanged事件。

這是我做的加載我的控制,有一個帆布:

  1. 訂閱用戶控件的加載事件(這是所有相關負載事件的目標(步驟調用和大小事件#2))。
  2. 訂閱大小更改事件(調用#1中提到的控件加載事件)。
  3. 所有從屬性OnXXXPropertyChanged事件調用OnLoad(#1)。
  4. 在加載的事件中,我檢查this.ActualWidth被設置(非零)以及是否所有依賴屬性都有效。 (如果它們都沒有設置,並且我的布爾全局標誌聲明它尚未加載;它什麼都不做並退出(等待下一個調用)。
  5. 一旦我的加載事件檢測到所有相關屬性已設置並且ActualWidth的不爲零的話,就開始使用寬度和從屬屬性來開始創建我的子控制的過程。

HTH