WPF_ Scroll WPF Listview to specific line
来源:互联网 发布:linux mint 字体 编辑:程序博客网 时间:2024/06/03 15:02
Scroll WPF Listview to specific line
WPF, Browserlike app.
I got one page containing a ListView. After calling a PageFunction I add a line to the ListView, and want to scroll the new line into view:
ListViewItem item = ItemContainerGenerator.ContainerFromIndex(index) as ListViewItem;
if (item != null)
ScrollIntoView(item);
This works. As long as the new line is in view the line gets the focus like it should.
Problem is, things don't work when the line is not visible.
If the line is not visible, there is no ListViewItem for the line generated, so ItemContainerGenerator.ContainerFromIndex returns null.
But without the item, how do I scroll the line into view? Is there any way to scroll to the last line (or anywhere) without needing an ListViewItem?
6 Answers
I think the problem here is that the ListViewItem is not created yet if the line is not visible. WPF creates the Visible on demand.
So in this case you probably get null
for the item, do you? (According to your comment, you do)
I have found a link on MSDN forums that suggest accessing the Scrollviewer directly in order to scroll. To me the solution presented there looks very much like a hack, but you can decide for yourself.
Here is the code snippet from the link above:
VirtualizingStackPanel vsp = (VirtualizingStackPanel)typeof(ItemsControl).InvokeMember("_itemsHost", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic, null, _listView, null);
double scrollHeight = vsp.ScrollOwner.ScrollableHeight;
double offset = scrollHeight * itemIndex_ / _listView.Items.Count; // itemIndex_ is index of the item which we want to show in the middle of the view
vsp.SetVerticalOffset(offset);
Someone told me an even better way to scroll to a specific line, which is easy and works like charm.
In short:
public void ScrollToLastItem()
{
lv.SelectedItem = lv.Items.GetItemAt(rows.Count - 1);
lv.ScrollIntoView(lv.SelectedItem);
ListViewItem item = lv.ItemContainerGenerator.ContainerFromItem(lv.SelectedItem) as ListViewItem;
item.Focus();
}
The longer version in MSDN forums:
I made some changes to Sam's answer. Note that I wanted to scroll to the last line. Unfortunately the ListView sometiems just displayed the last line (even when there were e.g. 100 lines above it), so this is how I fixed that:
public void ScrollToLastItem()
{
if (_mainViewModel.DisplayedList.Count > 0)
{
var listView = myListView;
listView.SelectedItem = listView.Items.GetItemAt(_mainViewModel.DisplayedList.Count - 1);
listView.ScrollIntoView(listView.Items[0]);
listView.ScrollIntoView(listView.SelectedItem);
//item.Focus();
}
}
Cheers
One workaround to this is to change the ItemsPanel of the ListView. The default panel is the VirtualizingStackPanel which only creates the ListBoxItem the first time they become visible. If you don't have too many items in your list, it should not be a problem.
<ListView>
...
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Thanks for that last tip Sam. I had a dialog which opened, meaning my grid lost focus every time the dialog closed. I use this:
if(currentRow >= 0 && currentRow < lstGrid.Items.Count) {
lstGrid.SelectedIndex = currentRow;
lstGrid.ScrollIntoView(lstGrid.SelectedItem);
if(shouldFocusGrid) {
ListViewItem item = lstGrid.ItemContainerGenerator.ContainerFromItem(lstGrid.SelectedItem) as ListViewItem;
item.Focus();
}
} else if(shouldFocusGrid) {
lstGrid.Focus();
}
Try this ` private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) { ScrollViewer scrollViewer = GetScrollViewer(lstVw) as ScrollViewer; scrollViewer.ScrollToHorizontalOffset(dataRowToFocus.RowIndex); if (dataRowToFocus.RowIndex < 2) lstVw.ScrollIntoView((Entity)lstVw.Items[0]); else lstVw.ScrollIntoView(e.AddedItems[0]); }
public static DependencyObject GetScrollViewer(DependencyObject o) { if (o is ScrollViewer) { return o; }
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
{
var child = VisualTreeHelper.GetChild(o, i);
var result = GetScrollViewer(child);
if (result == null)
{
continue;
}
else
{
return result;
}
}
return null;
}
private void Focus() { lstVw.SelectedIndex = dataRowToFocus.RowIndex; lstVw.SelectedItem = (Entity)dataRowToFocus.Row;
ListViewItem lvi = (ListViewItem)lstVw.ItemContainerGenerator.ContainerFromItem(lstVw.SelectedItem); ContentPresenter contentPresenter = FindVisualChild(lvi); contentPresenter.Focus(); contentPresenter.BringIntoView();
} `
- WPF_ Scroll WPF Listview to specific line
- listView -----------> scroll to specifyed
- jQuery 实现table卷轴移动(How to scroll to specific item using jQuery?)
- Forcing WPF to use a specific Windows theme
- WPF 处理RichTextBox, ListView等的Scroll Bar 事件(event)
- Scroll to fixed line in RichEidt in delphi
- WPF _Make ListView.ScrollIntoView Scroll the Item into the Center of the ListView (C#)
- The color chooser class, you could slide the scroll bars to get the specific numbers of the color
- Distributing to Specific Screens
- java编程之Noncompliant; %n should be used in place of \n to produce the platform-specific line separato
- ListView加入Scroll事件
- listview scroll pix
- ListView fast scroll style
- android-Distributing to Specific Screens
- Upload file to specific folder
- WPF ListView
- [.NET]ListView的Scroll事件
- 解决各种Scroll嵌套listview
- AJAX与callback的区别
- shutdown weblogic with force option
- android1.5模拟器无线上网
- java -D 参数
- PHP对象相互引用的内存溢出
- WPF_ Scroll WPF Listview to specific line
- 模块计算机类型“THUMB”与目标计算机类型“ARM”冲突 解决办法
- WCF后续之旅(2): 如何对Channel Layer进行扩展——创建自定义Channel
- UrlRewriteFilter
- ulimit linux 调优
- to_char 数值函数
- SNMP的应用
- 恢复ORACLE,出现RMAN-06059 错误信息
- [zz] shell判断文件,目录是否存在或者具有权限