Как переопределить MeasureOverride, чтобы найти размер ItemsControl - PullRequest
5 голосов
/ 13 января 2012

Я разрабатываю UserControl, который состоит из блока с заголовком и списком элементов (как ItemsControl). Пользовательский контроль динамически добавляется на холст. Мне нужно получить фактический размер элемента управления (включая пространство, занятое ItemsControl), прежде чем он будет визуализирован. Я попытался переопределить MeasureOverride метод UserControl, надеясь, что размер будет отражен в свойстве DesiredSize. Но это не работает.

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>   

Я переопределяю MeasureOverride пользовательского элемента управления, как показано ниже:

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

Код клиента:

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

Я не получаю фактический размер, используя свойство DesiredSize.Height от клиента. Есть идеи, как это исправить?

Ответы [ 2 ]

1 голос
/ 13 января 2012

Определяется ли ваш пользовательский элемент управления изменением высоты в зависимости от размера содержимого?По умолчанию ваш пользовательский элемент управления будет фиксированного размера и не будет изменяться по высоте только потому, что в элементе управления есть больше записей.

Я думаю, что вам нужно добавить свой пользовательский элемент управления в сетку, прежде чем измерять сетку.Вот как я измеряю элементы управления, и, кажется, это работает хорошо, даже если измерение непосредственно не работает, как в вашем случае ...

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 голосов
/ 13 января 2012

Попробуйте использовать свойства ActualWidth и 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...