2011-12-28 59 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