RelayCommand一段时间后停止工作 [英] RelayCommand stops working after a while

查看:247
本文介绍了RelayCommand一段时间后停止工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在面临使用GalaSoft的RelayCommand一些问题。



我有一个 NextCommand 属性的作品,但只有几次。



之后,它停止工作完全。



您可以用示例项目尝试了这一点:



http://s000.tinyupload.com/?file_id=65828891881629261404



行为如下:




  1. NextCommand

    1. 弹出的所有项目,直到活跃指数

    2. 如果有剩下不到50个项目,推1个新项目

    3. 标志着新项目为活动


  2. BackCommand

    1. 1个职位将活动指数重回




步骤复制:




  1. 的'+'(OemPlus)键已经绑定NextCommand

  2. 的' - '(OemMinus)键已经绑定BackCommand

  3. 按住+键,直到列表停止增长(50项限制)

  4. 按住 - 键,直到在列表中的第一项是活动

  5. 重复



需要重复(复制错误)是不一致的。数



有时候,我得到它后,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 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:

  1. NextCommand:

    1. pops all items until the active index
    2. if there are less than 50 items left, pushes 1 new item
    3. marks new item as active

  2. BackCommand:

    1. moves the active index back by 1 position

Steps to replicate:

  1. the '+' (OemPlus) key has been bound to NextCommand
  2. the '-' (OemMinus) key has been bound to BackCommand
  3. Hold the '+' key until the list stops growing (50 items limit)
  4. Hold the '-' key until the first item in the list is the active
  5. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆