2012-01-13 12 views
5

Opracowuję UserControl, który składa się z bloku z nagłówkiem i listą pozycji (jako ItemsControl). Kontrola użytkownika jest dynamicznie dodawana do płótna. Muszę uzyskać rzeczywisty rozmiar formantu (łącznie z miejscem zajmowanym przez ItemsControl), zanim zostanie on wyrenderowany. Próbowałem przesłonić metodę UserControl, mając nadzieję, że rozmiar zostanie odzwierciedlony we właściwości DesiredSize. Ale to nie działa.Jak zastąpić MeasureOverride, aby znaleźć rozmiar ItemsControl

XAML jest:

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

Jestem przesłanianie MeasureOverride z UserControl jak pokazano poniżej:

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

Kod Klient:

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

nie otrzymuję rozmiar rzeczywisty za pomocą właściwości DesiredSize.Height od klienta. Każdy pomysł, jak to naprawić?

Odpowiedz

-1

Spróbuj użyć właściwości ActualWidth i 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

To nie działa. – blitzkriegz

+1

ActualWidth i ActualHeight nie są ważne, dopóki nie zakończy się przejście układu. – Jeff

1

Czy zdefiniowano kontrolę użytkownika w celu zmiany wysokości, aby odzwierciedlić rozmiar zawartości? Domyślnie kontrola użytkownika będzie miała stały rozmiar, a nie zmianę wysokości tylko dlatego, że kontrola elementów ma więcej wpisów.

Wydaje mi się, że trzeba dodać kontrolę użytkownika w sieci przed pomiarem siatki. W ten sposób mierzę kontrole i wygląda na to, że działają dobrze, nawet jeśli bezpośredni pomiar nie działa tak jak w twoim przypadku ...

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

Tak, jest przeznaczony do zmiany wysokości na podstawie liczby elementów. – blitzkriegz

+0

Potrzebuję narysować linie między kontrolkami użytkownika. Z tego powodu dodałem funkcję usercontrol do obszaru roboczego. Próbuję uzyskać rzeczywistą wysokość, aby określić punkty połączenia. – blitzkriegz

+0

Czy można zaproponować inną metodę rysowania połączeń bez użycia obszaru roboczego. – blitzkriegz

Powiązane problemy