RelayCommand在一段时间后停止工作
我使用GalaSoft的RelayCommand遇到了一些问题。
我有一个可以工作的NextCommand属性,但只有几次。
之后,它完全停止工作。
您可以使用示例项目尝试此操作:
http://s000.tinyupload.com/?file_id=65828891881629261404
行为如下:
- NextCommand :
- 弹出所有项目直到活动索引
- 如果剩下少于50个项目,则推送1个新项目
- 将新项目标记为活动
- BackCommand :
- 将活动索引向后移动1个位置
复制步骤:
- ‘+’(OemPlus)键已绑定到NextCommand
- ‘ – ‘(OemMinus)键已绑定到BackCommand
- 按住“+”键直到列表停止增长(限制50个项目)
- 按住“ – ”键,直到列表中的第一项处于活动状态
- 重复
所需的重复次数(复制错误)是不一致的。
有时我会在重复4次后得到它; 其他时间直到9。
// Items Collection public class ItemCollection : ViewModelBase { // List of Items private readonly ObservableCollection _items = new ObservableCollection(); public ObservableCollection Items { get { return _items; } } // Constructor public ItemCollection() { BackCommand = new RelayCommand( () => { // Go to previous page var index = Items.IndexOf(ActiveItem); if (index > 0) { ActiveItem = Items[index - 1]; } }, () => ActiveItem != null && Items.IndexOf(ActiveItem) > 0); } // Back command public RelayCommand BackCommand { get; set; } // Next command public RelayCommand NextCommand { get; set; } // The currently-active item private Item _activeItem; public Item ActiveItem { get { return _activeItem; } set { Set(() => ActiveItem, ref _activeItem, value); } } } // Item public class Item : ViewModelBase { public string Title { get; set; } }
当我进入RelayCommand的代码时,执行操作的isAlive标志为false。 但我似乎无法弄清楚这可能会如何发生。
两个字: 垃圾收集器
在您的示例项目中 – 您应该发布相关的部分以使您的问题面向未来 – 您在窗口上设置DataContext
,如下所示:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var logic = new LogicObject(); DataContext = logic.Collection; } }
因为没有其他内容保留对LogicObject
创建的LogicObject
的引用,所以将在下一次机会时收集它。
该命令停止运行,因为在LogicObject
,您将ItemCollection
的NextCommand
设置为使用即将收集的LogicObject
私有成员:
public class LogicObject { public LogicObject() { Collection = new ItemCollection(); Collection.NextCommand = new RelayCommand(AddItem, CanAddItem); AddItem(); } private bool CanAddItem() { // snip... } private void AddItem() { // snip... } }
收集LogicObject
,该命令将无法再运行,因为它不再引用有效方法( AddItem
和CanAddItem
)。 这就是为什么RelayCommand
对这些方法的弱引用的isAlive
字段都是错误的。
您可以通过挂起LogicObject
或将AddItem
和CanAddItem
方法移动到集合中来解决此问题。
为了获得这个问题的GIF精神,这里显示了一旦Gen 0收集发生时按钮停止工作。
为什么不简单地使用ICollectionView中的方法? 你有:
- MoveCurrentTo
- MoveCurrentToFirst
- MoveCurrentToLast
- MoveCurrentToNext
- MoveCurrentToPrevious
- 和其他好东西
这样的事情
private ICollectionView MyView {get;set;} this.MyView = CollectionViewSource.GetDefaultView(this._items); if (!this.MyView.IsCurrentBeforeFirst) { this.MyView.MoveCurrentToPrevious(); }