2012-01-13 8 views
5

Estoy desarrollando un UserControl que consiste en un bloque con un encabezado y una lista de elementos (como ItemsControl). El control de usuario se agrega dinámicamente a un lienzo. Necesito obtener el tamaño real del control (incluido el espacio ocupado por ItemsControl) antes de que se represente. Traté de reemplazar el método MeasureOverride de UserControl esperando que el tamaño se reflejara en la propiedad DesiredSize. Pero no está funcionando.Cómo anular MeasureOverride para encontrar el tamaño de ItemsControl

El XAML es:

<UserControl x:Class="MyTools.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}}">  
    <Grid x:Name="LayoutRoot" Background="White"> 
     <Border Name="MainBorder" CornerRadius="5" BorderThickness="2" BorderBrush="Black"> 
     <Grid Name="grid1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" > 
      <Grid.RowDefinitions> 
       <RowDefinition Height="34" /> 
       <RowDefinition Height="*" /> 
      </Grid.RowDefinitions> 
      <Grid Name="titleGrid" Grid.Row="0" Background="#FF727272"> 
       <TextBlock Name="titleText" HorizontalAlignment="Center" Text="{Binding ControlName}" VerticalAlignment="Center" FontSize="13" FontWeight="Bold" Foreground="Beige" /> 
      </Grid> 
      <Grid Name="gridpr" Grid.Row="1" Background="#12C48F35"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="*" /> 
      </Grid.RowDefinitions> 
      <Border Name="borderPr" CornerRadius="3" Margin="10" BorderThickness="1" BorderBrush="LightGray" Grid.Row="0"> 
       <Grid Name="gridPr" Background="#FFC1C1C1" MouseLeftButtonUp="gridPr_MouseLeftButtonUp"> 
        <StackPanel> 
         <TextBlock HorizontalAlignment="Center" Name="txtPr" Text="SubItems" VerticalAlignment="Center" Foreground="#FF584848" FontSize="12" /> 
         <ItemsControl x:Name="pitems" ItemsSource="{Binding MyItems}" > 
          <ItemsControl.ItemTemplate> 
          <DataTemplate> 
          <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="15,0,0,0"> 
           <TextBlock Text="{Binding MyVal}" /> 
          </StackPanel> 
          </DataTemplate> 
         </ItemsControl.ItemTemplate> 
         </ItemsControl> 
        </StackPanel> 
       </Grid> 
      </Border> 
     </Grid> 
     </Grid> 
     </Border> 
    </Grid> 
</UserControl> 

estoy preponderantes con MeasureOverride del control de usuario, como se muestra a continuación:

namespace MyTools 
{ 
    public partial class MyControl : UserControl 
    { 
     public MyControl() 
     { 
      InitializeComponent(); 
     } 

     public string ControlName { get; set; } 
     public object MyItems { get; set; } 

     public class Row 
     { 
      public string MyVal { get; set; } 
     } 

     protected override Size MeasureOverride(Size availableSize) 
     { 
      var desiredSize = base.MeasureOverride(availableSize); 
      var sideLength = Math.Min(desiredSize.Width, desiredSize.Height); 

      desiredSize.Width = sideLength; 
      desiredSize.Height = sideLength; 

      return desiredSize; 
     } 
    } 
    } 

Código Cliente:

 MyControl control1 = new MyControl();   
     control1.ControlName = "Test Name"; 

     var test = new List<MyControl.Row>(
     new MyControl.Row[] 
      { 
       new MyControl.Row {MyVal = "Item1"}, 
       new MyControl.Row {MyVal = "Item2"}, 
       new MyControl.Row {MyVal = "Item3"} 
      }); 

     control1.MyItems = test; 

     control1.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
     MessageBox.Show(control1.DesiredSize.Height.ToString()); 
     canvas1.Children.Add(control1); 

No estoy recibiendo el tamaño real utilizando la propiedad DesiredSize.Height del cliente. Alguna idea de como arreglar esto?

Respuesta

-1

Intente utilizar las propiedades ActualWidth y ActualHeight.

protected override Size MeasureOverride(Size availableSize) 
{ 
    var desiredSize = new Size(); 
    var sideLength = Math.Min(ActualWidth, ActualHeight); 

    desiredSize.Width = sideLength; 
    desiredSize.Height = sideLength; 

    return desiredSize; 
} 
+0

Esto no está funcionando. – blitzkriegz

+1

ActualWidth y ActualHeight no son válidos hasta que se haya completado un pase de diseño. – Jeff

1

¿Está definido su control de usuario para cambiar de altura para reflejar el tamaño de los contenidos? De forma predeterminada, su control de usuario tendrá un tamaño fijo y no cambiará de altura solo porque el control de elementos tenga más entradas.

Creo que necesita agregar su control de usuario dentro de una grilla antes de medir la grilla. Así es como mido los controles y parece funcionar bien, incluso cuando la medición del control directamente no funciona como en su caso ...

MyControl control1 = new MyControl(); 

... your setup code for control1... 

Dim containerGrid As New Grid 
containerGrid.Children.Add(control1) 
containerGrid.Measure(New Size(Double.MaxValue, Double.MaxValue)) 
containerGrid.Arrange(New Rect(0, 0, Double.MaxValue, Double.MaxValue)) 

...now check the grid.ActualWidth and grid.ActualHeight 
+0

Sí, está diseñado para cambiar de altura según la cantidad de elementos. – blitzkriegz

+0

Necesito dibujar líneas entre los controles de usuario. Esa es la razón por la que estaba agregando el control de usuario a lienzo. Estoy tratando de obtener la Altura real para determinar los puntos de conexión. – blitzkriegz

+0

¿Puede sugerir otro método para dibujar conexiones sin utilizar lienzo? – blitzkriegz

Cuestiones relacionadas