我已经多次看到这个问题,并且一遍又一遍地检查了我的代码。但是当我用一个对象分配给我的SelectedItem
-bound 属性时,它不会更新显示的选定项目。似乎ListBox
认为我分配的对象不是其项目的成员。
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>
这是我尝试设置的地方之一的 impl SelectedTube
- 肯定发生在主线程上。
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
绝对是列表框中的对象。没运气。
这不是可见性的东西,如果该项目在屏幕上,它仍然不会突出显示。我需要实现某种平等功能吗?我在这件事上浪费的时间比人们想象的要多。
谢谢。