我有一个ListBox,它的ItemsSource绑定到一个自定义类上。该类已经(正确地)实现了INotifyCollectionChanged,并且SelectedItem绑定到ViewModel中的一个字段。
问题在于,当我从ItemsSource集合中删除一个当前SelectedItem时,它会立即更改选择为相邻项。我非常希望它只是取消选择。
导致问题的原因是,ItemsSource类包含来自其他集合的元素,这些元素要么满足某个(运行时常数)谓词,要么是Active。Active与SelectedItem“同步”(有理由)。因此,一个项目只有在被选中时才可以允许出现在ListBox中,这意味着当用户选择其他项目时,它可能应该消失。
我的函数(在“模型”深处)在SelectedItem更改时被调用:
问题在于,由于(#1)触发的
非常感谢任何帮助。
如果有人想深入了解实际代码:
问题在于,当我从ItemsSource集合中删除一个当前SelectedItem时,它会立即更改选择为相邻项。我非常希望它只是取消选择。
导致问题的原因是,ItemsSource类包含来自其他集合的元素,这些元素要么满足某个(运行时常数)谓词,要么是Active。Active与SelectedItem“同步”(有理由)。因此,一个项目只有在被选中时才可以允许出现在ListBox中,这意味着当用户选择其他项目时,它可能应该消失。
我的函数(在“模型”深处)在SelectedItem更改时被调用:
//Gets old Active item
var oldActiveSchema = Schemas.FirstOrDefault(sch => sch.IsActive);
//Makes the new Item active (which triggers adding it into `ItemsSource` in case it didn't satisfy the Predicate)
((PowerSchema)newActiveSchema).IsActive = true;
//Triggers PropertyChanged on ViewModel with the new Active item
CurrentSchema = newActiveSchema;
RaisePropertyChangedEvent(nameof(CurrentSchema)); (#1)
//Changes the old item so it stops being Active -> gets removed from `ItemsSource` (#2)
if (oldActiveSchema != null) { ((PowerSchema)oldActiveSchema).IsActive = false; }
问题在于,由于(#1)触发的
SelectedItem
更改而更新 ListBox
的原因被推迟了(更新 ListBox
的消息可能会进入WPF消息循环中并等待当前计算完成 )。
另一方面,从ItemsSource
中删除oldActiveSchema
是立即的,并且立即触发SelectedItem
的更改为接替旧选项的下一个选项(当您删除选定的项目时,会选择相邻的项目)。并且由于SelectedItem
的更改会触发我的函数,该函数将CurrentSchema
设置为错误的(相邻的)项目,因此它重写了用户选择的CurrentSchema
(#1),当由于PropertyChanged
更新 ListBox
的消息运行时,它只是使用相邻的一个更新它。非常感谢任何帮助。
如果有人想深入了解实际代码:
- ListBox
- ViewModel
- 模型方法
- 当相邻的项目作为
SelectedItem
而不是用户选择的项目被选中时的调用堆栈- 第46行:用户选择的
SelectedItem
作为要激活的对象进入该方法 - 第45行:旧的
SelectedItem
停止激活->从集合中删除(44-41) - 第32行:
MoveCurrencyOffDeletedElement
移动SelectedItem
- 第5行:
SelectedItem
更改为相邻的一个
- 第46行:用户选择的
#1
调用的消息被处理时,视图将加载正确的当前选定项(由上面的行设置)并且一切都将正常工作。 - Petrroll