C# WPF:调整大小后如何保持ListBox SelectedItem可见?
在我们当前的C# WPF:调整大小后如何保持ListBox SelectedItem可见?,c#,wpf,xaml,scroll,listbox,C#,Wpf,Xaml,Scroll,Listbox,在我们当前的C#MVVM项目中,我们使用列表框来显示项目 还有一个容器可以在列表框下面展开 一切正常。当容器展开时,列表框收缩并出现滚动条 但是,如果在列表框底部选择了一个元素并展开了容器,则该项将在列表框的末尾消失 例如: 容器扩展前: +--------------+ | Item 1 | +--------------+ | Item 2 | +--------------+ | Item 3 | +--------------+ | Item 4
C#
MVVM
项目中,我们使用列表框来显示项目
还有一个容器可以在列表框下面展开
一切正常。当容器展开时,列表框
收缩并出现滚动条
但是,如果在列表框底部选择了一个元素并展开了容器,则该项将在列表框的末尾消失
例如:
容器扩展前:
+--------------+
| Item 1 |
+--------------+
| Item 2 |
+--------------+
| Item 3 |
+--------------+
| Item 4 |
+--------------+
| SelectedItem |
+--------------+
| Item 6 |
+--------------+
| Item 7 |
+--------------+
+------------------+
| Container |
+------------------+
+--------------+---+
| Item 1 | S |
+--------------+ c |
| Item 2 | r |
+--------------+ o |
| Item 3 | l |
+--------------+ l |
| Item 4 | |
+--------------+---+
+------------------+
| |
| |
| Container |
| |
| |
+------------------+
容器扩展后:
+--------------+
| Item 1 |
+--------------+
| Item 2 |
+--------------+
| Item 3 |
+--------------+
| Item 4 |
+--------------+
| SelectedItem |
+--------------+
| Item 6 |
+--------------+
| Item 7 |
+--------------+
+------------------+
| Container |
+------------------+
+--------------+---+
| Item 1 | S |
+--------------+ c |
| Item 2 | r |
+--------------+ o |
| Item 3 | l |
+--------------+ l |
| Item 4 | |
+--------------+---+
+------------------+
| |
| |
| Container |
| |
| |
+------------------+
我想要实现的是保持可见SelectedItem
,而不必滚动到它
像这样:
+--------------+---+
| Item 2 | S |
+--------------+ c |
| Item 3 | r |
+--------------+ o |
| Item 4 | l |
+--------------+ l |
| SelectedItem | |
+--------------+---+
+------------------+
| |
| |
| Container |
| |
| |
+------------------+
实现这一目标的最佳方式是什么
我在这里找不到任何关于这件事的东西
我已经看到可以通过编程方式滚动:
我还看到,可以知道何时可以看到ListBoxItem
,但由于我的项目已经加载,然后隐藏,我认为这不起作用
我不想在需要这种功能的每个视图中都复制代码。我曾想过在列表框
的行为中实现这一点,但我非常怀疑这是最好的解决方案
我还考虑过编写一个自定义的列表框
控件,但我认为这对于这样一个小功能来说太多了
有人能告诉我实现这种行为的最佳方法吗?
提前感谢。A是将此功能添加到控件的理想方法。更改选择或调整大小后,下面的代码会将列表框的SelectedItem滚动到视图中
public class perListBoxHelper : Behavior<ListBox>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
AssociatedObject.SizeChanged += AssociatedObject_SizeChanged;
}
protected override void OnDetaching()
{
AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
AssociatedObject.SizeChanged -= AssociatedObject_SizeChanged;
base.OnDetaching();
}
private static void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ScrollSelectionIntoView(sender as ListBox);
}
private static void AssociatedObject_SizeChanged(object sender, SizeChangedEventArgs e)
{
ScrollSelectionIntoView(sender as ListBox);
}
private static void ScrollSelectionIntoView(ListBox listBox)
{
if (listBox?.SelectedItem == null)
return;
Action action = () =>
{
listBox.UpdateLayout();
listBox.ScrollIntoView(listBox.SelectedItem);
};
listBox.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
}
}
公共类perListBoxHelper:行为
{
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.SelectionChanged+=AssociatedObject\u SelectionChanged;
AssociatedObject.SizeChanged+=AssociatedObject\u SizeChanged;
}
附加时受保护的覆盖无效()
{
AssociatedObject.SelectionChanged-=AssociatedObject\u SelectionChanged;
AssociatedObject.SizeChanged-=AssociatedObject\u SizeChanged;
base.OnDetaching();
}
私有静态无效关联对象\u SelectionChanged(对象发送者,SelectionChangedEventArgs e)
{
滚动选择查看(发件人为列表框);
}
私有静态无效关联对象\u SizeChanged(对象发送方,SizeChangedEventArgs e)
{
滚动选择查看(发件人为列表框);
}
私有静态无效滚动选择视图(列表框列表框)
{
如果(列表框?.SelectedItem==null)
回来
动作动作=()=>
{
UpdateLayout();
listBox.ScrollIntoView(listBox.SelectedItem);
};
listBox.Dispatcher.BeginInvoke(操作,DispatcherPriority.ContextIdle);
}
}
用法
更多关于我最近的行为的讨论。非常感谢!这正是我需要的!我只是不明白为什么你也听selectionChanged,因为我们允许多重选择,所以不得不删除这个部分。但再一次,谢谢你。我会好好看看你的博客!SelectionChanged是此行为最初设计用来处理的-当您从代码隐藏或通过绑定选择项目时,它将滚动到视图中。哦,我明白了,谢谢!我不需要这个部分,因为它不会发生在我的情况下,但它可能会有用的一天。再次感谢你,也许最好是做出两种截然不同的行为——每一个事件一个。然后,您可以为每个特定的Listbox实例添加适当的内容。