如何覆盖MeasureOverride以查找ItemsControl的大小

时间:2012-01-13 01:59:41

标签: c# wpf silverlight user-controls

我正在开发一个UserControl,它包含一个带有标题和项目列表的块(如ItemsControl)。 usercontrol动态添加到画布。我需要在渲染之前获得控件的实际大小(包括ItemsControl占用的空间)。我尝试覆盖UserControl的MeasureOverride方法,希望大小会反映在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>   

我正在覆盖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 个答案:

答案 0 :(得分:1)

您的用户控件是否定义为更改高度以反映内容的大小?默认情况下,您的用户控件将是固定大小,而不会因为items控件具有更多条目而改变高度。

我认为您需要在网格中添加用户控件,然后再测量网格。这就是我测量控件的方法,它似乎运行良好,即使直接测量控件不能像你的情况一样工作......

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

答案 1 :(得分:-2)

尝试使用ActualWidthActualHeight属性。

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

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

   return desiredSize;
}