[英]RelayCommand stops working after a while
I am facing some problems using GalaSoft's RelayCommand. 我使用GalaSoft的RelayCommand遇到了一些问题。
I have a NextCommand property that works, but only several times. 我有一个可以工作的NextCommand属性,但只有几次。
Afterwards, it stops working completely. 之后,它完全停止工作。
You can try this out with the sample project: 您可以使用示例项目尝试此操作:
http://s000.tinyupload.com/?file_id=65828891881629261404 http://s000.tinyupload.com/?file_id=65828891881629261404
The behaviour is as follows: 行为如下:
Steps to replicate: 复制步骤:
The number of repetitions needed (to replicate the bug) is inconsistent. 所需的重复次数(复制错误)是不一致的。
Sometimes I get it after 4 repetitions; 有时我会在重复4次后得到它; other times up till 9.
其他时间到9。
// Items Collection
public class ItemCollection : ViewModelBase
{
// List of Items
private readonly ObservableCollection<Item> _items = new ObservableCollection<Item>();
public ObservableCollection<Item> 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; }
}
When I stepped into the RelayCommand's code, the execute action's isAlive flag was false. 当我进入RelayCommand的代码时,执行操作的isAlive标志为false。 But I can't seem to figure out how that might happen.
但我似乎无法弄清楚这可能会如何发生。
Two words: Garbage Collector 两个字: 垃圾收集器
In your example project--which you should post the relevant bits of to make your question future-proof--you set the DataContext
on your window like this: 在您的示例项目中 - 您应该发布相关的部分以使您的问题面向未来 - 您在窗口上设置
DataContext
,如下所示:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var logic = new LogicObject();
DataContext = logic.Collection;
}
}
Because nothing else retains a reference to the LogicObject
created here, it will be collected at the next opportunity. 因为没有别的东西保留对这里创建的
LogicObject
的引用,所以它将在下一次机会时收集。
The command stops functioning because in LogicObject
, you set the NextCommand
of the ItemCollection
to use private members of the soon-to-be-collected 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...
}
}
Once LogicObject
is collected, the command can no longer work because it no longer has references to valid methods ( AddItem
and CanAddItem
). 收集
LogicObject
,该命令将无法再运行,因为它不再引用有效方法( AddItem
和CanAddItem
)。 This is why the isAlive
field on both of the RelayCommand
's weak references to the methods is false. 这就是为什么
RelayCommand
对这些方法的弱引用的isAlive
字段都是错误的。
You can fix this by just hanging on to the LogicObject
, or by moving the AddItem
and CanAddItem
methods into the collection. 您可以通过挂起
LogicObject
或将AddItem
和CanAddItem
方法移动到集合中来解决此问题。
To get in the spirit of GIFs for this question, here's one that shows the button stop working as soon as a Gen 0 collection occurs. 为了获得这个问题的GIF精神,这里有一个显示按钮在Gen 0收集发生时立即停止工作的问题。
why dont you simply use the methods from ICollectionView? 为什么不简单地使用ICollectionView中的方法? there you have:
你有:
something like this 这样的事情
private ICollectionView MyView {get;set;}
this.MyView = CollectionViewSource.GetDefaultView(this._items);
if (!this.MyView.IsCurrentBeforeFirst)
{
this.MyView.MoveCurrentToPrevious();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.