如何使自定义子项的列表框布局无效

时间:2010-03-22 06:06:21

标签: wpf wpf-controls

我有一个列表框的自定义面板

<ItemsPanelTemplate x:Key="FloatPanelTemplate">
    <Controls:FloatPanel x:Name="CardPanel" />
</ItemsPanelTemplate>

该面板使用其X和Y依赖项属性布置其子项。 当FloatPanel单独使用时,这一切都很好用 - 我正在使用FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure有关子项的依赖项属性,以告知FloatPanel重绘其布局。

当我在列表框(上面的代码)中使用它时,它第一次绘制就好了,但是当我拖动子项(修改项目的X和Y)时,它没有通知列表框它需要重绘FloatPanel的儿童。我认为这个问题与绑定集合中的每个项都包含一个ListBoxItem这一事实有关。

希望我已经描述了我做得很好,有人可以告诉我如何使面板(或其子)告诉它需要再次执行布局例程。正如我所说,它工作一次(初始绘制),但拖动项目不起作用(列表框不知道它的子项已更改,需要重新布局。)如果我拖动一个项目然后调整窗口大小,列表框将执行布局和这些物品是在新的位置绘制的。

如何通知ListBox(或更重要的是ItemsPanelTemplate中的FloatPanel)需要进行布局传递?

2 个答案:

答案 0 :(得分:1)

而是尝试使用FrameworkPropertyMetadataOptions.AffectsParentMeasure和FrameworkPropertyMetadataOptions.AffectsParentArrange。

那些名字......感谢上帝为intellisense,是吗?

正如您所指出的那样,由于ListBoxItem是您元素的直接布局父级,因此对于父级布局的依赖项属性的更改将不会被可视树上的面板“看到”。

因此,遗憾的是,您可能需要遍历可视树,直到找到从Panel派生的元素并调用其InvalidateArrange方法。

DependencyObject obj=this;
while ( (obj=VisualTreeHelper.GetParent(obj)) != null) {
    Panel p = obj as Panel;
    if (p != null) {
        p.InvalidateArrange();
        break;
    }
}

这很难看,但也许WPF大师会有更好的建议。

答案 1 :(得分:0)

您确定ListBoxListView小组似乎没有显示不正确的尺寸,因为它有......

ScrollViewer.CanContentScroll="True"

...这是默认值?

当列表控件处于此模式时,当它滚动到底部时,其面板的底部可能会有额外的空白,以确保整齐的项目排成一行在其内部ScrollViewer顶部,这可能看起来像ScrollViewer - 因此列表控件 - 没有调整自身大小。

要防止面板底部出现空白,必须在ListBox或ListView控件上启用按像素滚动:

ScrollViewer.CanContentScroll="False"

或代码:

ScrollViewer.SetCanContentScroll(list_ctrl, false);

另请参阅:WPF ListView non integral scrolling