我见过这个问题,问了很多次,并且遍历了我的代码。但是,当我使用对象分配到SelectedItem
-bound属性时,它不会更新显示的选定项目。看来,ListBox
认为我分配的对象不是它的项目的成员。ListBox TwoWay绑定到SelectedItem
public class MainViewModel : ViewModelBase
{
//...
public SortedObservableCollection<TubeViewModel> Items { get; private set; }
public TubeViewModel SelectedTube { //get, set, propertychanged, etc. }
}
<ListBox x:Name="TubeList"
Margin="10"
ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource TubeTemplate}"
SelectedItem="{Binding SelectedTube, Mode=TwoWay}"
SelectionMode="Single"
VirtualizingStackPanel.IsVirtualizing="False">
</ListBox>
下面是从那里我尝试设置SelectedTube
的地方之一IMPL - 肯定会出现在主线程上。
var match =
from t in Items
where t.Model.DataFileName == filename
select t;
if (match.Any())
SelectedTube = match.First();
我注意到,在SelectedTube
从未强调,除非我手动点击就可以了,但那种忽略了它。但后来我想ScrollIntoViewCentered的选定项目,所以我在我看来加了一个DependencyProperty
来观察SelectedItem
的变化。该处理器最初看起来像这样:
private void OnSelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
if (TubeList.SelectedItem == null)
return;
TubeList.ScrollIntoViewCentered(TubeList.SelectedItem);
}
但是,如果我通过我的绑定设置SelectedItem
没有工作。决定我想只有滚动它,如果它不是在屏幕上后,我改变了代码如下:
private void OnSelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
if (TubeList.SelectedItem == null)
return;
var container = TubeList.ItemContainerGenerator.ContainerFromItem(TubeList.SelectedItem) as FrameworkElement;
if(!container.IsVisible)
TubeList.ScrollIntoViewCentered(TubeList.SelectedItem);
}
如果SelectedItem
外部设定,容器是空的。每次。我甚至添加了代码来检查null,然后遍历ItemsSource
查找文件名匹配,然后更新SelectedItem
以确保SelectedItem
绝对是列表框中的一个对象。没有运气。
这不是一个可见性的东西,如果该项目在屏幕上,它仍然不会突出显示。我是否需要实现某种平等功能?我浪费了更多的时间,而不是人们可能会想到的。
谢谢。
我无法用我们看到的代码重现这一点。我为TubeViewModel制作了一个虚拟类,并使用了所有发布的代码,并按预期工作。某些事情必须在其他地方发生。 – 2009-12-15 18:32:00
非常感谢Ben和Kent。我休假了一段时间,这将不得不等待。 – Thomas 2009-12-15 20:22:59