【发布时间】:2010-11-11 15:05:40
【问题描述】:
我在PopupControl 中有一个ListBox。问题是在滚动时,Popup 会调整大小
以适应实际最宽的元素。
如何避免这种调整大小并自动调整到整个列表中最宽的元素?
我尝试将其放入Grid,但没有成功。
【问题讨论】:
-
您能否根据其内容计算特定 ListBoxItem 的宽度?
我在PopupControl 中有一个ListBox。问题是在滚动时,Popup 会调整大小
以适应实际最宽的元素。
如何避免这种调整大小并自动调整到整个列表中最宽的元素?
我尝试将其放入Grid,但没有成功。
【问题讨论】:
好的,这是解决方案:添加此属性
<ListBox VirtualizingStackPanel.IsVirtualizing="False"
调整大小停止,因为现在 Panel 包含所有元素并且调整了宽度 尊重最广泛的。 使用虚拟化面板,它只是显示的项目的一部分,列表框将宽度调整为实际可见的最宽元素。
缺点是,我们不再使用Virtualizing Panel(默认开启)
【讨论】:
如果您想继续进行虚拟化,可以将Popup.Width 设置为常量。
当然,要选择正确的常数,您必须计算(或至少猜测)每个 ListBoxItem 的宽度,然后选择最大值。 ...通常根据您的内容,粗略猜测并不难。
【讨论】:
我遇到了与上述完全相同的问题 - 我的 ListBox 不会虚拟化,因为它会忙于在可调整大小的 PopUp 控件中进行布局。我找到的解决方案是限制包含ListBox 的网格的MaxWidth 和MaxHeight。我的PopUp 控件仍然可以通过 Grip 调整大小 - 它只是在它可以占用的空间中不是无限的 - 我认为一旦知道这可以解决问题,那就放弃一个简单的解决方案:-)
我知道ListBox 正在虚拟化,因为包含大约 18,000 个元素的查询会在 1-2 秒而不是 30-60 秒内得到回答,并且滚动速度很快而不是冻结。
<Popup x:Name="PART_Popup"
AllowsTransparency="true"
PlacementTarget="{Binding ElementName=PART_ContentHost}"
Placement="Bottom"
IsOpen="{Binding IsPopupOpened, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
PopupAnimation="None"
Focusable="False"
StaysOpen="True"
>
<Border BorderBrush="{TemplateBinding PopupBorderBrush}"
BorderThickness="{TemplateBinding PopupBorderThickness}"
Background="{DynamicResource {x:Static reskeys:ResourceKeys.ControlPopupBackgroundBrushKey}}"
>
<!-- Do NOT REMOVE MaxHeight and MaxWidth
These ensure that containing ListBox is virtualizing -->
<Grid x:Name="PART_ResizeableGrid" Background="Transparent"
MaxHeight="600"
MaxWidth="600"
>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border
x:Name="DropDownBorder"
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
Width="{Binding ActualWidth, ElementName=PART_ContentHost}"
Height="{Binding ActualHeight, ElementName=PART_ContentHost}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.RowSpan="2"
BorderThickness="0"
/>
<ListBox
x:Name="PART_ItemList" Grid.Row="0"
HorizontalAlignment="Stretch" VerticalAlignment="Top"
ItemsSource="{Binding Suggestions, RelativeSource={RelativeSource TemplatedParent}}"
BorderThickness="0"
ItemTemplate="{TemplateBinding ItemTemplate}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Template="{DynamicResource {x:Static reskeys:ResourceKeys.PopListBoxControlTemplate}}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
SelectedValuePath="{TemplateBinding ValuePath}"
KeyboardNavigation.AcceptsReturn="True"
KeyboardNavigation.DirectionalNavigation="Cycle"
BorderBrush="{TemplateBinding BorderBrush}"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.IsDeferredScrollingEnabled="True"
/>
<!-- RezizeGrip Thumb to support resizing the suggestion lib -->
<Thumb x:Name="PART_ResizeGripThumb"
Grid.Row="0"
Style="{DynamicResource {x:Static reskeys:ResourceKeys.ResizeGripStyleKey}}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="0"
Background="Transparent"
Width="16"
Height="16" />
</Grid>
</Border>
</Popup>
【讨论】:
大多数 WPF UIElement 控件都有一个 Width 属性,可以将其设置为“Auto”,因此它们占用的空间与其最宽的元素一样多。
【讨论】: