5

我已经多次看到这个问题,并且一遍又一遍地检查了我的代码。但是当我用一个对象分配给我的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绝对是列表框中的对象。没运气。

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

谢谢。

4

3 回答 3

5

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

ItemContainerGenerators在询问属性之前尝试调用 UpdateLayout() 。

于 2010-01-06T11:43:57.027 回答
3

没有什么让我觉得明显是错误的,但你已经掩饰了很多。我只能建议您简化事情,直到您找到问题,或者有一个完整的非工作示例可以发布。

于 2009-12-15T18:08:30.330 回答
1

您是否尝试根据您要设置的对象的哈希码检查 itemsource 中每个对象的哈希码?Linq 查询将返回不同的内容。

作为尝试将 SelectedTube 设置为 Items[0] 的测试。

于 2010-01-06T01:26:46.687 回答