ListBox TwoWay绑定到SelectedItem

时间:2009-12-15 17:37:25

标签: wpf data-binding 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>

这是我尝试设置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绝对是列表框中的对象。没运气。

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

感谢。

3 个答案:

答案 0 :(得分:5)

也许这也与ItemContainerGenerators在单独的线程中生成的事实有关...(at least in the TreeView

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

答案 1 :(得分:3)

对我而言,没有任何事情显然是错误的,但你已经掩饰了很多。我只能建议你简化一些事情,直到找到问题,或者有一个完整的非工作示例,你可以发布。

答案 2 :(得分:1)

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

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