【发布时间】:2012-07-02 10:32:00
【问题描述】:
我需要知道 ListBox 第一次完成渲染的时间,以便我可以将其滚动到顶部以向用户展示列表中的第一项。
我有一个ListBox,它在DataTemplate 中使用RichTextBox:
<DataTemplate x:Key="HelpTextTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
...
<ContentControl>
...
<RichTextBox x:Name="HelpTextContent" Grid.Row="1"
Tag="{Binding Path=HelpObject.Text, Mode=TwoWay}"
TextWrapping="Wrap"
HorizontalAlignment="Stretch"
Margin="0,0,20,0"
Loaded="RichTextBox_Loaded"
ContentChanged="RichTextBox_ContentChanged"
SelectionChanged="RichTextBox_SelectionChanged"/>
...
</ContentControl>
...
</Grid>
</DataTemplate>
ListBox 绑定到 ObservableCollection。
ListBox 的滚动出现问题 - 如果RichTextBox 的高度大于ListBox 的高度,则用户无法滚动到RichTextBox 的底部。 ListBox 将跳转到列表中的下一项。滚动条滑块的高度也会改变。这是因为RichTextBox 的实际高度仅在实际渲染时计算。当它离开屏幕时,高度会恢复为较小的值(我认为代码假定文本可以全部放在一行而不是必须被换行)。
我将这些问题追溯到ListBox 使用VirtualisingStackPanel 来绘制项目。当我用简单的StackPanel 替换它时,这些问题就消失了。
这造成了我现在遇到的问题,即ListBox 在初始加载时滚动到列表底部。 ListBox 上的 Loaded 和 LayoutUpdated 事件在数据加载之前发生。当 ObservableCollection 初始化时,我尝试在视图模型上监听 PropertyChanged 事件:
void editViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "ListDataSource":
// Try to scroll to the top of the ListBox
break;
}
}
这也触发得太早了。该列表在此事件被触发并导致ListBox 滚动到底部后呈现。
【问题讨论】:
标签: silverlight listbox rendering