ListBox TwoWay绑定到SelectedItem

Tho*_*mas 5 data-binding wpf listbox selecteditem two-way-binding

我已经多次看到这个问题并且一遍又一遍地查看我的代码.但是,当我SelectedItem使用对象分配我的绑定属性时,它不会更新显示的选定项.看来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>
Run Code Online (Sandbox Code Playgroud)

这是我尝试设置的其中一个地方的impl SelectedTube- 肯定发生在主线程上.

 var match =
    from t in Items
    where t.Model.DataFileName == filename
    select t;
 if (match.Any())
    SelectedTube = match.First();
Run Code Online (Sandbox Code Playgroud)

我注意到,SelectedTube除非我手动点击它,否则从未突出显示,但有点忽略它.但后来我想ScrollIntoViewCentered所选项目,所以我DependencyProperty在我的视图中添加了一个观察SelectedItem更改.处理程序最初看起来像这样:

private void OnSelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
    if (TubeList.SelectedItem == null)
       return;

    TubeList.ScrollIntoViewCentered(TubeList.SelectedItem);
}
Run Code Online (Sandbox Code Playgroud)

但如果我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);
}
Run Code Online (Sandbox Code Playgroud)

如果SelectedItem是外部设置,则容器为空.每次.我甚至添加了代码来检查null,然后迭代ItemsSource查找文件名匹配,然后更新SelectedItem以确保SelectedItem绝对是列表框中的对象.没运气.

这不是一个可见性的东西,如果项目在屏幕上,它仍然不会突出显示.我需要实现某种平等功能吗?我浪费的时间比人们想象的要多.

谢谢.

Max*_*kin 5

也许这也与ItemContainerGenerators在单独的线程中生成的事实有关...(至少在TreeView中)

在询问ItemContainerGenerators酒店之前,请尝试调用UpdateLayout().