Wpf 虚拟化面板,不使用';t作物项目

Wpf 虚拟化面板,不使用';t作物项目,wpf,scrollview,itemscontrol,.net-4.5,virtualizingstackpanel,Wpf,Scrollview,Itemscontrol,.net 4.5,Virtualizingstackpanel,因此,如果项目在滚动区域的末尾被剪切/裁剪,那么拥有一个无铬的集合看起来真的很愚蠢 我想为集合(ItemsControl/ListBox)创建一个虚拟化面板,它只绘制整个项目,而不绘制项目片段。例如: ______________ | | |______________| ______________ | | |______________| ______________ | | 我不希望显示第三个部分容器,

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

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

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

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

有什么建议吗?我是否应该尝试重新发明轮子(构建我自己的
虚拟化HoleiTempanel

编辑


Microsoft澄清说,
virtualizangpanel.ScrollUnit
根本不打算执行此功能。似乎
virtualizangpanel.ScrollUnit
的用途与
ScrollViewer

上的旧
CanContentScroll
非常相似。我有一个助手方法,用于确定控件在父容器中是否部分或完全可见。您可能可以将其与
转换器一起使用来确定项目的可见性

您的转换器可能需要从UI项计算父容器(如果您愿意,我的博客中有一组可以提供帮助),也可能是一个同时接受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;
}
我使用了您在问题中发布的XAML,并在
.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>


您是否正在更改
VirtualizingPanel.ScrollUnit
的设置?因为,默认情况下,它被设置为
,这就是您要查找的内容。可能会发布一些代码和屏幕截图,因为这是一个开发者预览,如果它真的是一个bug,你可以向Microsoft Connect提交一份问题单?我正在明确地将
ScrollUnit
设置为
。我将编辑并添加我的示例代码。据我所知,这是虚拟化的一个“特性”。对于速度,当重复使用显示容器时,它不会重新计算宽度。您可以尝试水平内容对齐=拉伸。或者,您可以迭代字符串列表,并明确设置宽度以适应最大值。或者你可以设置一个你认为最能处理的固定宽度,然后打开文本包装。我不担心宽度,我只担心显示整个/完整的容器。这些项目不会被裁剪,因为主体不够宽。
ScrollViewer
正在裁剪它们。也许您应该使用Microsoft在您的:)控件中提供的新信息更新您的问题。可见性可以变成
[Flags]
枚举。没有改变游戏规则,只是一个建议。@m-y:我不认为有任何理由让它成为一个标志枚举。该值不应等于多个可能性。据我所知,标志枚举用于将多个值与布尔值&、|连接在一起。嗯,
Full
FullHeightPartialWidth
,和
FullWidthPartialHeight
似乎是相关的值。@m-y脚本的最初目的是在按钮列表超过允许的宽度时用下拉菜单替换按钮列表,有些模板允许部分可见的项目,而其他模板则不允许。我觉得枚举比标志更具描述性,Josh说得对,一个控件永远不会返回超过一个
ControlVisibility
Value半打或其他,这不是一个要求。这仅仅是一个与.NET代码行为一致的建议:例如,查看
比较选项
,其中标记了
标志
,即使某些组合可能没有意义。不过,这两种方法都会奏效,就像5而不是(2+3)一样。
<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>