RelayCommand一段时间后停止工作 [英] RelayCommand stops working after a while
问题描述
我现在面临使用GalaSoft的RelayCommand一些问题。
我有一个 NextCommand 属性的作品,但只有几次。
之后,它停止工作完全。
您可以用示例项目尝试了这一点:
的 http://s000.tinyupload.com/?file_id=65828891881629261404
行为如下:
- NextCommand :
- 弹出的所有项目,直到活跃指数
- 如果有剩下不到50个项目,推1个新项目
- 标志着新项目为活动
- BackCommand :
- 1个职位将活动指数重回
步骤复制:
- 的'+'(OemPlus)键已经绑定NextCommand
- 的' - '(OemMinus)键已经绑定BackCommand
- 按住+键,直到列表停止增长(50项限制)
- 按住 - 键,直到在列表中的第一项是活动
- 重复
需要重复(复制错误)是不一致的。数
有时候,我得到它后,4次重复;其他时间截止到9。
//项目集合
公共类ItemCollection:ViewModelBase
{
//名单项目
私人只读的ObservableCollection<的;项目> _items =新的ObservableCollection<项目>();
公众的ObservableCollection<项目>项目
{
{返回_items; }
}
//构造
公共ItemCollection()
{
BackCommand =新RelayCommand(
()=>
{
//转到上一页
VAR指数= Items.IndexOf(ActiveItem);
如果(指数大于0)
{
ActiveItem =项目[指数 - 1];!
}
},
()=> ActiveItem = NULL&放大器;&安培; Items.IndexOf(ActiveItem)0);
}
//返回命令
公共RelayCommand BackCommand {搞定;组; }
//下一个命令
公共RelayCommand NextCommand {搞定;组; }
//当前活动的项目
私人物品_activeItem;
公共项目ActiveItem
{
{返回_activeItem; }
组
{
组(()=> ActiveItem,楼盘_activeItem,价值);
}
}
}
//项目
公共类项目:ViewModelBase
{
公共字符串名称{搞定;组; }
}
当我踏进RelayCommand的代码中,执行行动的的isAlive 标志是假的。但我似乎无法弄清楚如何可能发生
两个词:垃圾收集
在实例项目 - 这你应该张贴的相关位,使您的问题面向未来 - 将的DataContext
你的窗口像这样的:
公共部分类主窗口:窗口
{
酒店的公共主窗口()
{
的InitializeComponent();
变种逻辑=新LogicObject();
的DataContext = logic.Collection;
}
}
由于闲来无事保留在<$ C参$ C> LogicObject 在这里创建,它将在下次有机会收集。
命令停止在 LogicObject
,将 NextCommand
的 ItemCollection
使用soon-的私有成员待收集 LogicObject
:
公共类LogicObject
{
公共LogicObject()
{
系列=新ItemCollection();
Collection.NextCommand =新RelayCommand(的AddItem,CanAddItem);
的AddItem();
}
私人布尔CanAddItem()
{
//略...
}
私人无效的AddItem( )
{
//略...
}
}
在 LogicObject
被收集,命令不能再工作,因为它不再有(以有效的方法的引用的AddItem
和 CanAddItem
)。这就是为什么双方的 RelayCommand
的弱引用的的isAlive
字段的方法是错误的。
您可以通过只挂到 LogicObject
,或通过移动的AddItem 解决这个问题code>和
CanAddItem
方法到集合。
要获得的GIF对这个问题的精神,这里有一个显示按钮,只要一第0集时停止工作。
按钮失败
I am facing some problems using GalaSoft's RelayCommand.
I have a NextCommand property that works, but only several times.
Afterwards, it stops working completely.
You can try this out with the sample project:
http://s000.tinyupload.com/?file_id=65828891881629261404
The behaviour is as follows:
- NextCommand:
- pops all items until the active index
- if there are less than 50 items left, pushes 1 new item
- marks new item as active
- BackCommand:
- moves the active index back by 1 position
Steps to replicate:
- the '+' (OemPlus) key has been bound to NextCommand
- the '-' (OemMinus) key has been bound to BackCommand
- Hold the '+' key until the list stops growing (50 items limit)
- Hold the '-' key until the first item in the list is the active
- Repeat
The number of repetitions needed (to replicate the bug) is inconsistent.
Sometimes I get it after 4 repetitions; other times up till 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. 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:
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.
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
:
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
). This is why the isAlive
field on both of the RelayCommand
's weak references to the methods is false.
You can fix this by just hanging on to the LogicObject
, or by moving the AddItem
and CanAddItem
methods into the collection.
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.
这篇关于RelayCommand一段时间后停止工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!