我有一个ListBox,其Style和ItemTemplate在点击特定按钮时在代码隐藏中更改。
listbox.ItemTemplate = FindResource("dataTemplateView1") as DataTemplate;
listbox.Style = FindResource("listBoxStyle1") as Style;
有三种可能的视图,因此有三组数据模板和样式。 DataTemplate包含一些文本和缩略图(每组不同的大小)。样式只是将ItemsPanelTemplate更改为WrapPanel,StackPanel(水平)和StackPanel(垂直)。例如:
<Style x:Key="listBoxStyle1" TargetType={x:Type ListBox}">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
问题在于,当我有一个选定的项目(比如索引为20的项目)并且我更改了视图时,显示的列表框的可见区域将重置回第一个索引(但是所选项目仍然被选中,只是没有显示)。
我尝试使用解决方案here来解决此问题,以滚动到所选项目并将其设置为居中。但目前,有时候行为似乎不稳定,因为发生的事情是列表框中的第一项首先显示然后跳转到所选项目。还有其他选择吗?
谢谢!
答案 0 :(得分:1)
您所寻找的内容与我在之前的回答中所写的内容并无太大差异。
两个不同之处是:
这两个问题可以一起解决如下(参考我之前对相关代码细节的回答):
box.ItemContainerGenerator.ContainerFromItem(box.SelectedItem)
获取商品容器container.TransformToAncestor(box).Transform(new Point())
以获取容器相对于列表框的左上角。 (如果您希望将项目的中心保持静止,请改用new Point(container.DesiredSize.Width/2, container.DesiredSize.Height/2)
。)box.ItemContainerGenerator.ContainerFromItem(box.SelectedItem)
获取商品容器container.TransformToAncestor(box).Transform(new Point())
以获取新容器相对于列表框的左上角这将在没有闪烁的情况下工作的原因是这里的所有内容都是同步发生的,因此Render优先级的调度程序操作不会运行。成本是UpdateLayout()相对昂贵。
另请注意,如果您的任何单个项目已实施,以便在初始测量/安排后更改其大小(例如在调度程序回调中),那么您将需要重新定位两次:一旦进入同步代码,则再次在调度员回调中。在这种情况下,我知道防止闪烁的唯一可靠的通用方法是修复项目的实现,以便在初始布局完成之前获得它们的大小。
答案 1 :(得分:0)
这是一个品味问题,但我会触发淡出和淡入动画大概.15或.2秒,并在模板切换淡出时进行。这将隐藏滚动并平滑布局中非常突然的切换。