2012-01-13 12 views
5

Sto sviluppando un UserControl costituito da un blocco con un'intestazione e un elenco di elementi (come ItemsControl). L'usercontrol viene aggiunto dinamicamente a una tela. Devo ottenere la dimensione effettiva del controllo (incluso lo spazio preso da ItemsControl) prima che venga eseguito il rendering. Ho provato a sovrascrivere il metodo MeasureOverride di UserControl sperando che la dimensione si riflettesse nella proprietà DesiredSize. Ma non sta funzionando.Come sovrascrivere MeasureOverride per trovare la dimensione di ItemsControl

Il XAML è:

<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> 

sto Overriding MeasureOverride di UserControl come illustrato di seguito:

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; 
     } 
    } 
    } 

Codice 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); 

Non ricevo la dimensione reale utilizzando la proprietà DesiredSize.Height dal client. Qualche idea su come risolvere questo problema?

risposta

-1

Provare a utilizzare le proprietà ActualWidth e 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

Questo non funziona. – blitzkriegz

+1

ActualWidth e ActualHeight non sono validi fino al completamento di un passaggio di layout. – Jeff

1

È il controllo dell'utente definito per modificare l'altezza per riflettere la dimensione dei contenuti? Per impostazione predefinita, il controllo utente avrà una dimensione fissa e non cambierà di altezza solo perché il controllo degli elementi ha più voci.

Penso che sia necessario aggiungere il controllo utente all'interno di una griglia prima di misurare la griglia. Questo è il modo in cui misuro i controlli e sembra funzionare bene, anche quando il controllo diretto non funziona come nel tuo 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ì, è progettato per modificare l'altezza in base al numero di elementi. – blitzkriegz

+0

Devo disegnare delle linee tra gli usercontrols. Questo è il motivo per cui aggiungevo l'usercontrol alla tela. Sto cercando di ottenere l'altezza effettiva per determinare i punti di connessione. – blitzkriegz

+0

Puoi suggerire qualsiasi altro metodo per disegnare le connessioni senza usare canvas. – blitzkriegz

Problemi correlati