问题描述
我正在开发一个 UserControl,它由一个带有标题的块和一个项目列表(如 ItemsControl
)组成.用户控件被动态添加到画布.我需要在呈现控件之前获取控件的实际大小(包括 ItemsControl
占用的空间).我尝试覆盖 UserControl 的 MeasureOverride
方法,希望大小能反映在 DesiredSize
属性中.但它不起作用.
I am developing a UserControl that consists of a block with a heading and a list of items (as ItemsControl
). The usercontrol is added dynamically to a canvas. I need to get the actual size of the control (including space taken by ItemsControl
) before it gets rendered. I tried overriding MeasureOverride
method of the UserControl hoping that the size would be reflected in DesiredSize
property. But it is not working.
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,如下所示:
I am overriding MeasureOverride of the UserControl as shown below:
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
属性获取实际大小.知道如何解决这个问题吗?
I am not getting the actual size using the DesiredSize.Height
property from the client. Any idea on how to fix this?
推荐答案
您的用户控件是否定义为改变高度以反映内容的大小?默认情况下,您的用户控件将是固定大小,不会因为项目控件具有更多条目而改变高度.
Is your user control defined to change in height to reflect the size of the contents? By default your user control will be a fixed size and not change in height just because the items control has more entries.
我认为您需要先在网格中添加用户控件,然后再测量网格.这就是我测量控件的方式,它似乎运行良好,即使直接测量控件与您的情况不同......
I think you need to add your user control inside a grid before then measuring the grid. This is how I measure controls and it seems to work well, even when measuring the control directly does not work as in your case...
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
这篇关于如何覆盖 MeasureOverride 以查找 ItemsControl 的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!