在渲染之前获取用户控件的实际大小

6

我正在尝试在UserControl类中使用Measure方法,在MyUserControl被渲染之前获取其的实际大小,这是为了解决我之前提出的问题。然而这种方法并不起作用。 MyUserControl有一个ItemsControl,它绑定了一个List,如下所示,通过uc.MyCollection = myCollection;添加的项没有反映在uc.DesiredSize.Height中。

MyUserControl uc= new MyUserControl();
uc.AName = "a1";
uc.Width = 194;
uc.MyCollection = myCollection; //myCollection is  a List databound to ItemsControl inside MyUserControl
uc.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
uc.Arrange(new Rect(0, 0, uc.DesiredSize.Width, uc.DesiredSize.Width)); //Needed?
uc.UCHeight = uc.DesiredSize.Height; //size of items databound to ItemsControl not reflected here
uc.UCWidth = uc.DesiredSize.Width;
uc.Margin = new Thickness(34, 42, 0, 0);
myRoot.Children.Add(uc); //myRoot is Canvas

3
尝试在调用“Measure()”之前将“uc”添加到根,然后在访问“DesiredSize”之前执行“UpdateLayout()”。这是我通常做的。 - kev
@neutrino:什么没有起作用?这些值是0还是不精确? - Tigran
数值并非精确值。高度未考虑ItemsControl中项的高度。 - softwarematter
你的 ListBox 是否在 Canvas 中?Canvas 不会根据其可视化父级或子级调整大小,如果没有明确设置,它的 DesiredSize 为 0。 - terphi
3个回答

6

您需要在自己的用户控件中重写MeasureOverride和ArrangeOverride方法来计算大小。在MeasureOverride内部,使用"Measure"方法 "询问"您的列表它自己的大小 - 这样您就可以计算出自己用户控件的大小(在MeasureOverride中返回此大小)- 然后在调用uc.Measure后您将获得所需大小。


2
我非常确定您只需在自定义面板实现中实现这些方法。UC只是其他控件的组合,因此不必实现这些方法。 - ColinE
如果用户控件具有绑定到列表的ItemsControl怎么办?创建用户控件后,我正在将List属性分配给UserControl的ItemsControl。问题是,对usercontrol的Measure调用返回DesiredSize.Height,而不考虑ItemsControl的高度。 - softwarematter

1

你的ItemsControl绑定到MyCollection将不会在用户控件处于VisualTree之前进行处理,因此在调用Measure时,desiredsize仍为0。

当我需要获取FrameworkElement的大小时,我将其Opacity设置为0,将其添加到可视树中,并等待SizeChanged事件。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接