gpt4 book ai didi

wpf - 不裁剪项目的虚拟化面板

转载 作者:行者123 更新时间:2023-12-04 19:32:44 25 4
gpt4 key购买 nike

因此,如果项目在滚动区域的末尾被剪切/裁剪,那么拥有无 Chrome 集合看起来真的很愚蠢。

我想为集合 (ItemsControl/ListBox) 创建一个虚拟化面板,它只绘制整个项目,而不是项目的片段。例如:

 ______________
| |
|______________|
______________
| |
|______________|
______________
| |

enter image description here

我不希望显示第三个部分容器,除非有空间可以显示整个项目/容器。在示例中,由于空间不足,第三项被裁剪。

有什么建议?我应该尝试重新发明轮子(构建我自己的 VirtualizingWholeItemPanel)吗?

编辑 :

微软澄清说 VirtualizingPanel.ScrollUnit根本不打算执行此功能。看来 VirtualizingPanel.ScrollUnit与旧的 CanContentScroll 的用途非常相似在 ScrollViewer .

最佳答案

我有一个辅助方法,用于确定控件在父容器中是部分可见还是完全可见。您可能可以将它与 Converter 一起使用以确定项目的可见性。

您的转换器要么需要根据 UI 项计算父容器(我的博客有一组 Visual Tree Helpers,如果您愿意,可以帮助解决此问题),或者它可能是 MultiConverter接受 UI 项和父容器作为参数。

ControlVisibility ctrlVisibility= 
WPFHelpers.IsObjectVisibleInContainer(childControl, parentContainer);

if (ctrlVisibility == ControlVisibility.Full
|| isVisible == ControlVisibility.FullHeightPartialWidth)
{
return Visibility.Visible;
}
else
{
return = Visibility.Hidden;
}

确定控件在其父控件中可见性的代码如下所示:
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.ActualWidth, child.ActualHeight)));

Rect result = Rect.Intersect(
new Rect(new Point(0, 0), parent.RenderSize), childSize);

if (result == Rect.Empty)
{
return ControlVisibility.Hidden;
}
if (Math.Round(result.Height, 2) == childSize.Height
&& Math.Round(result.Width, 2) == childSize.Width)
{
return ControlVisibility.Full;
}
if (result.Height == childSize.Height)
{
return ControlVisibility.FullHeightPartialWidth;
}
if (result.Width == childSize.Width)
{
return ControlVisibility.FullWidthPartialHeight;
}
return ControlVisibility.Partial;
}

编辑

做了一些测试,显然转换器在控件实际呈现之前运行。作为一个黑客,如果你使用 MultiConverter 它将起作用并将它传递给 ActualHeight控件,这将强制转换器在控件呈现时重新评估。

这是我使用的转换器:
public class TestConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
FrameworkElement child = values[0] as FrameworkElement;
var parent = VisualTreeHelpers.FindAncestor<ListBox>(child);

ControlVisibility ctrlVisibility =
VisualTreeHelpers.IsObjectVisibleInContainer(child, parent);

if (ctrlVisibility == ControlVisibility.Full
|| ctrlVisibility == ControlVisibility.FullHeightPartialWidth)
{
return Visibility.Visible;
}
else
{
return Visibility.Hidden;
}
}

public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
return null;
}
}

我使用了您在问题中发布的 XAML,并为 ListBoxItem 添加了隐式样式在 .Resources
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Visibility">
<Setter.Value>
<MultiBinding Converter="{StaticResource Converter}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding RelativeSource="{RelativeSource Self}" Path="ActualHeight" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>

关于wpf - 不裁剪项目的虚拟化面板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9416047/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com