我第一次发帖:)
我的UserControl宽度出现了这个问题,我似乎无法弄明白。
基本上我有一个包含ItemsControl的UserControl(panle是一个水平StackPanel)。该项的DataTemplate是一个标准Button。 我将一个字符串List绑定到ItemsControl,每个字符串都绑定到Button的Content属性。到目前为止工作正常。
我需要做的是跟踪ItemsControl中每个单项(带有字符串的按钮)的宽度,即使它们没有被渲染。我需要动态地(在调整大小时)删除超过UserControl最大宽度的项目,并在有足够空间的情况下再次添加它们。
为实现此目的,我使用以下函数测量每个字符串的宽度:
private double GetTextWidth(string text)
{
FormattedText ft = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(this.FontFamily, this.FontStyle, this.FontWeight, this.FontStretch), this.FontSize, this.Foreground);
ft.Trimming = TextTrimming.CharacterEllipsis;
return ft.WidthIncludingTrailingWhitespace;
}
然后我手动为返回值添加6的边距,此边距是Button所需的间距。 对我的List中的字符串中的所有生成值求和,我应该得到与UserControl几乎相同的宽度。由于所有布局都被拉伸(即使是窗口中的UserControl),也没有边距或填充(据我所见),并且只有一个宽度为1的边框。
问题是这不起作用,它要求我手动将一个非常大的值(45-65单位)添加到计算的宽度,以使其工作“像素完美”。
我显然试图找到这个问题的根源,但却无法解决。 首先我认为它是由DIP< - >引起的。像素问题,但似乎并非如此。 我测量了单个字符串的宽度,然后测量了包含相同字符串的按钮的宽度。在所有情况下,第一个和第二个相差6个单位。 按钮之间没有可见的空间,所以我真的无法解释这么多开销来自哪里。 我唯一注意到的是,如果我改变FontSize,我需要添加的值会发生变化,但这很明显......
可能我错过了一些重大的想法? 谢谢你的阅读!
答案 0 :(得分:0)
如果我理解正确,您希望隐藏屏幕上不完全可见的项目。
我过去使用辅助方法完成此操作,该方法将告诉我控件是否完全可见,并且如果控件不完全可见,则将控件的可见性设置为Hidden
。我是在Loaded
和SizeChanged
事件中实现的。
这是帮助类,它返回渲染控件的可见性:
public enum ControlVisibility
{
Hidden,
Partial,
Full,
FullHeightPartialWidth,
FullWidthPartialHeight
}
/// <summary>
/// Checks to see if an object is rendered visible within a parent container
/// </summary>
/// <param name="child">UI element of child object</param>
/// <param name="parent">UI Element of parent object</param>
/// <returns>ControlVisibility Enum</returns>
public static ControlVisibility IsObjectVisibleInContainer(
FrameworkElement child, UIElement parent)
{
GeneralTransform childTransform = child.TransformToAncestor(parent);
Rect childSize = childTransform.TransformBounds(
new Rect(new Point(0, 0), new Point(child.Width, child.Height)));
Rect result = Rect.Intersect(
new Rect(new Point(0, 0), parent.RenderSize), childSize);
if (result == Rect.Empty)
{
return ControlVisibility.Hidden;
}
if (result.Height == childSize.Height && result.Width == childSize.Width)
{
return ControlVisibility.Full;
}
if (result.Height == childSize.Height)
{
return ControlVisibility.FullHeightPartialWidth;
}
if (result.Width == childSize.Width)
{
return ControlVisibility.FullWidthPartialHeight;
}
return ControlVisibility.Partial;
}
Loaded
和SizeChanged
事件背后的代码看起来像这样:
ControlVisibility ctrlVisibility=
WPFHelpers.IsObjectVisibleInContainer(button, parent);
if (ctrlVisibility == ControlVisibility.Full
|| isVisible == ControlVisibility.FullWidthPartialHeight)
{
button.Visibility = Visibility.Visible;
}
else
{
button.Visibility = Visibility.Hidden;
}