我已经多次看过这个问题并且一遍又一遍地查看我的代码。但是当我用一个对象分配给我的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
绝对是列表框中的对象。没运气。
这不是一个可见性的东西,如果该项目在屏幕上,它仍然不会突出显示。我需要实现某种平等功能吗?我浪费的时间比人们想象的还要多。
感谢。
答案 0 :(得分:5)
也许这也与ItemContainerGenerators
在单独的线程中生成的事实有关...(at least in the TreeView)
在询问ItemContainerGenerators
属性之前尝试调用UpdateLayout()。
答案 1 :(得分:3)
对我而言,没有任何事情显然是错误的,但你已经掩饰了很多。我只能建议你简化一些事情,直到找到问题,或者有一个完整的非工作示例,你可以发布。
答案 2 :(得分:1)
您是否尝试针对您尝试设置的对象的哈希码检查itemsource中每个对象的哈希码? Linq查询将返回不同的内容。
尝试将SelectedTube设置为Items [0]。